2014-05-08 24 views
1

我想要得到的std :: true_type如果以下表達式編譯:SFINAE檢查是否表達編譯並返回的std :: true_type

template<typename T> 
static constexpr std::true_type check(T*) ?????? 
std::declval<T>().func_name(std::declval<Args>()...) // method to check for 

和std :: false_type否則我通常用做

template<typename> 
static constexpr std::false_type check(...); 

我搜索類似於enable_if的東西,如果表達式編譯,它返回一個常量類型。似乎很容易,但打破我的頭:-)

+7

'decltype(STD :: declval ().func_name(STD :: declval () ...),void(),std :: true_type {})' –

+0

是的,這樣的工作,但從來沒有見過一個decltype與3 parms之前...我會尋找手冊。謝謝!讓它成爲答案,我可以接受! – Klaus

+1

@Klaus那些是'運營商,'不是多個參數。 – Yakk

回答

0

我個人使用(使用完全簽名):

#include <cstdint> 

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)    \ 
    template <typename U, typename... Args>         \ 
    class traitsName              \ 
    {                  \ 
    private:                \ 
     template<typename T, T> struct helper;        \ 
     template<typename T>            \ 
     static std::uint8_t check(helper<signature, &funcName>*);   \ 
     template<typename T> static std::uint16_t check(...);    \ 
    public:                 \ 
     static                \ 
     constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \ 
    } 
你的情況

因此,使用這樣的:

DEFINE_HAS_SIGNATURE(has_func_name, T::func_name, void (T::*)(Args...)); 

和測試它喜歡:

struct C 
{ 
    void func_name(char, int); 
}; 

static_assert(has_func_name<C, char, int>::value, "unexpected non declared void C::func_name(char, int)"); 
static_assert(!has_func_name<C, int, int>::value, "unexpected declared void C::func_name(int, int)");