2017-02-03 9 views
0

Следующий код проверяет, существует ли метод foo() в классе A. Этот код компилируется под vs2013, но статическое утверждение не выполняется на vs2015. Какая версия компилятора говорит правду? Если 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"); 

ответ

5

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");