I've made a hybrid traits generator macro that checks for either members or free standing functions.
This creates template traits classes that look whether a user supplied signature (first template arg) works with the name embedded in the traits class.
It looks for free-standing names if no second template param is supplied (Trait<Sig>::value
), or for a member of the second template argument if the traits template is instantiated with two arguments (Trait<Sig,ClassToSearch>::value
).
It can only search for free functions that were declared before the Traits template class was defined.
#define DEF_HAS_SIG(TraitsName, funcName) \
std::nullptr_t funcName(...); \
template<typename Sig, typename Type=void> class TraitsName { \
typedef char yes[1]; \
typedef char no [2]; \
template <typename U, U> struct TypeCheck; \
template <typename _1, typename _2 > static no &chk(...); \
template <typename _1, typename _2> static \
typename std::enable_if< std::is_same<void,_2>::value, yes&>::type chk(TypeCheck<_1, &funcName > *); \
template <typename _1, typename _2> static yes& chk(TypeCheck<_1, &_2::funcName > *); \
public: static bool const value = sizeof(chk<Sig,Type>(0)) == sizeof(yes); \
};