4

この構造体を考えてみましょう:

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

SFINAE を使用してこのメ​​ソッドの一貫性を検出することは可能ですか?

たとえば、次のように使用できる特性でこのプロパティをキャプチャしたいと思いますstatic_assert

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

std::is_constここでは or のどちらかが役立つと思いstd::remove_constましたが、この「タイプ」の性質を包含していないようですconst.

ありがとう、

4

2 に答える 2

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!");
}
于 2012-12-21T15:41:49.230 に答える
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 {};

C スタイルの可変個引数関数をキャタリングするためにさらに特殊化を追加することもできますが、率直に言って、私は気にしません。

于 2012-12-21T15:42:13.130 に答える