2012-12-21 47 views
4

考慮這個結構:是否可以使用SFINAE檢測類的方法的常量?

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這個「類型」。

感謝,

回答

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!"); 
} 
+0

爲什麼所有的非''const'的特殊化,如果你默認從'false_type'派生? – Xeo

+2

因爲我沒有R.馬丁尼費爾南德斯那麼聰明。 :-)我從我已經寫過的其他代碼中複製/粘貼這些代碼,我需要列舉所有不同的可能性。它看起來很乏味,直到你記住沒有可變參數的情況下試圖做到這一點是什麼樣的! :-) –

+0

請在下一次會議中爲模板中的'ref_qualifier'和'cv_qualifier'佔位符爭論。 ;) – Xeo

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 {}; 

你也可以添加更多的專門化catter爲C風格的參數可變功能,但坦白說,親愛的,我不給該死。

相關問題