由一道C++面试题引发的思考 - 知乎
//判断是否存在指定的成员函数名
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