是否可以使用SFINAE检测类方法的常量?

piw*_*iwi 4 c++ templates boost sfinae c++11

考虑这个结构:

struct foo {
  void dummy() const {}
};
Run Code Online (Sandbox Code Playgroud)

是否可以使用SFINAE检测此方法的常量?

例如,我想在一个可用于以下内容的特征中捕获此属性static_assert:

static_assert(is_const_method<decltype(&foo::dummy)>::value, "Not const!");
Run Code Online (Sandbox Code Playgroud)

我认为这里std::is_const或者std::remove_const会帮助我,但他们似乎并没有包含这种"类型" const.

谢谢,

How*_*ant 12

当然,看起来像这样:

#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!");
}
Run Code Online (Sandbox Code Playgroud)

  • 因为我不像R. Martinho Fernandes那么聪明.:-)而且我从我已经写过的其他代码中复制/粘贴了这些,我需要列举所有不同的可能性.它看起来很乏味,直到你记得在没有可变参数的情况下尝试这样做是什么感觉!:-) (2认同)

R. *_*des 11

您可以使用部分特化.

// 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 {};
Run Code Online (Sandbox Code Playgroud)

您还可以为C风格的可变参数功能添加更多特化,但坦率地说,亲爱的,我不会给出该死的.