//判断是否存在指定的成员函数名
template <typename T, typename = void>
struct HasMemF_Fun : public std::false_type {};
template <typename T>
struct HasMemF_Fun<T, std::void_t<decltype(&T::Fun123)>>
: std::is_member_function_pointer<decltype(&T::Fun123)> {};
//判断是否存在指定的成员变量名
template <typename T, typename = void>
struct HasMemV_Name : public std::false_type {};
template <typename T>
struct HasMemV_Name<T, std::void_t<decltype(&T::name123)>>
: std::is_member_object_pointer<decltype(&T::name123)> {};
struct XXX
{
void Fun123() {}
std::wstring name123;
};
int main()
{
if (HasMemV_Name<XXX>::value)
{
std::cout << "XXX::name123 exists" << std::endl;
}
if (HasMemF_Fun<XXX>::value)
{
std::cout << "XXX::Fun123 exists" << std::endl;
}
}
运行结果:
XXX::name123 exists
XXX::Fun123 exists
#define DEFINE_MEMBERFUNCTION_TRAIT(name, func) \
template <typename T, typename = void> \
struct name : public std::false_type {}; \
\
template <typename T> \
struct name<T, std::void_t<decltype(&T::func)>> \
: std::is_member_function_pointer<decltype(&T::func)> {}; \
#define DEFINE_MEMBERVARIABLE_TRAIT(name, memVariable) \
template <typename T, typename = void> \
struct name : public std::false_type {}; \
\
template <typename T> \
struct name<T, std::void_t<decltype(&T::memVariable)>> \
: std::is_member_object_pointer<decltype(&T::memVariable)> {};\
DEFINE_MEMBERFUNCTION_TRAIT(HasFun123, Fun123)
DEFINE_MEMBERVARIABLE_TRAIT(HasName123, name123)
struct XXX
{
void Fun123() {}
std::wstring name123;
};
int main()
{
if (HasFun123<XXX>::value)
{
std::cout << "XXX::Fun123 exists" << std::endl;
}
if (HasName123<XXX>::value)
{
std::cout << "XXX::name123 exists" << std::endl;
}
}
执行结果:
XXX::Fun123 exists
XXX::name123 exists
另一个例子:
c++ - How do we use void_t for SFINAE? - Stack Overflow
template< class, class = void >
struct has_member : std::false_type
{ };
// specialized as has_member< T , void > or discarded (SFINAE)
template< class T >
struct has_member< T, std::void_t< decltype(T::member) > > : std::true_type
{ };
class A00 {
public:
int member;
};
class B00 {
};
int main()
{
static_assert(has_member< A00 >::value, "A");
static_assert(has_member< B00 >::value, "B");
}