我正在寻找一个SFINAE解决方案,以便在编译时检查类型是否有方法.我的目标是检查类型是否是有效的"鸭子类型",但我想static_assert用来提供信息性消息,而不是无用的编译错误.
我发现[这个问题],它为我的问题提供了一个相当不错的答案,除了它在类型为方法提供重载时失败:
template<typename...> // parameter pack here
using void_t = void;
template<typename T, typename = void>
struct has_xxx : std::false_type {};
template<typename T>
struct has_xxx<T, void_t<decltype(&T::xxx)>> :
std::is_member_function_pointer<decltype(&T::xxx)>{};
Run Code Online (Sandbox Code Playgroud)
这适用于以下示例,并区分方法和成员变量:
struct Foo { int xxx() {return 0;}; };
struct Foo2 {};
struct Foo3{ static double xxx;};
double Foo3::xxx = 42;
int main() {
static_assert(has_xxx<Foo>::value, "");
static_assert(!has_xxx<Foo2>::value, "");
static_assert(!has_xxx<Foo3>::value, "");
}
Run Code Online (Sandbox Code Playgroud)
如果出现过载,代码将失败:
struct Foo { int xxx() {return 0;} void xxx(int){} };
int main() {
static_assert(has_xxx<Foo>::value, ""); …Run Code Online (Sandbox Code Playgroud)