是否可以使用 SFINAE 检测类方法的恒定性?

Is it possible to detect the constness of a class' method using SFINAE?

本文关键字:恒定性 类方法 检测 可以使 SFINAE 是否      更新时间:2023-10-16

考虑此结构:

struct foo {
  void dummy() const {}
};

是否可以使用sfinae?

检测该方法的构成

例如,我想在static_assert中可用的特征中捕获此属性:

static_assert(is_const_method<decltype(&foo::dummy)>::value, "Not const!");

我以为std::is_conststd::remove_const在这里对我有帮助,但它们似乎并不包含const NESS的"类型"。

谢谢,

当然,看起来像这样:

#include <type_traits>
template <class T>
struct is_const_method
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...)>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const>
    : std::true_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) volatile>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const volatile>
    : std::true_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) &>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const &>
    : std::true_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) volatile &>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const volatile &>
    : std::true_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) &&>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const &&>
    : std::true_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) volatile &&>
    : std::false_type
{
};
template <class R, class C, class ...T>
struct is_const_method<R (C::*)(T...) const volatile &&>
    : std::true_type
{
};
struct foo {
  void dummy() const {}
};
int main()
{
    static_assert(is_const_method<decltype(&foo::dummy)>::value, "Not const!");
}

您可以使用部分专业。

// false by default
template <typename Fun>
struct is_const_function : std::false_type {};
// breakdown member function type
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const> : std::true_type {};
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const volatile> : std::true_type {};
// consider ref-qualified ones for compilers that support it
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const&> : std::true_type {};
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const&&> : std::true_type {};
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const volatile&> : std::true_type {};
template <typename Class, typename Result, typename... Args>
struct is_const_function<Result (Class::*)(Args...) const volatile&&> : std::true_type {};

您还可以为C风格的Variadic功能添加更多的专业,但坦率地说,亲爱的,我不给我该死。