方法存在检查器代码在 vs2015 中中断
method existence checker code breaks in vs2015
以下代码检查class A中是否存在foo()方法。这段代码是在vs2013下编译的,但是在vs2015上静态断言失败。哪个编译器版本说的是实话?如果是vs2015,那么怎么修复代码?
#include <type_traits>
struct MethodTester_foo {
template<typename U, typename MethodType>
static auto test(U* p) -> decltype(static_cast<MethodType>(U::foo));
template<typename U, typename MethodType> static auto test(...)->std::false_type;
};
template <typename Class, typename MethodType, class MethodTester>
using HasMethod =
typename std::conditional
<
std::is_same<
decltype(MethodTester::template test<Class, MethodType>(0)),
std::false_type
>::value,
std::false_type, std::true_type
>::type;
struct A { int foo() { return 1; } };
static_assert(HasMethod<A, int(A::*)(), MethodTester_foo>::value, "Has no method named foo");
2015 年是正确的。您需要 &U::foo
而不是 U::foo
。 &ClassName::methodName
是在 C++ 中获取成员函数指针的唯一方法。
顺便说一句,您的代码可以大大简化:
#include <type_traits>
struct MethodTester_foo {
template<typename U, typename MethodType, typename = decltype(static_cast<MethodType>(&U::foo))>
static auto test(U* p) -> std::true_type;
template<typename U, typename MethodType>
static auto test(...) -> std::false_type;
};
template <typename Class, typename MethodType, class MethodTester>
using HasMethod = decltype(MethodTester::template test<Class, MethodType>(0));
struct A { int foo() { return 1; } };
static_assert(HasMethod<A, int(A::*)(), MethodTester_foo>::value, "Has no method named foo");
以下代码检查class A中是否存在foo()方法。这段代码是在vs2013下编译的,但是在vs2015上静态断言失败。哪个编译器版本说的是实话?如果是vs2015,那么怎么修复代码?
#include <type_traits>
struct MethodTester_foo {
template<typename U, typename MethodType>
static auto test(U* p) -> decltype(static_cast<MethodType>(U::foo));
template<typename U, typename MethodType> static auto test(...)->std::false_type;
};
template <typename Class, typename MethodType, class MethodTester>
using HasMethod =
typename std::conditional
<
std::is_same<
decltype(MethodTester::template test<Class, MethodType>(0)),
std::false_type
>::value,
std::false_type, std::true_type
>::type;
struct A { int foo() { return 1; } };
static_assert(HasMethod<A, int(A::*)(), MethodTester_foo>::value, "Has no method named foo");
2015 年是正确的。您需要 &U::foo
而不是 U::foo
。 &ClassName::methodName
是在 C++ 中获取成员函数指针的唯一方法。
顺便说一句,您的代码可以大大简化:
#include <type_traits>
struct MethodTester_foo {
template<typename U, typename MethodType, typename = decltype(static_cast<MethodType>(&U::foo))>
static auto test(U* p) -> std::true_type;
template<typename U, typename MethodType>
static auto test(...) -> std::false_type;
};
template <typename Class, typename MethodType, class MethodTester>
using HasMethod = decltype(MethodTester::template test<Class, MethodType>(0));
struct A { int foo() { return 1; } };
static_assert(HasMethod<A, int(A::*)(), MethodTester_foo>::value, "Has no method named foo");