2017-10-08 8 views
2

제공된 클래스에 정적 메서드가 있는지 여부를 검색하는 메커니즘을 구현하려고합니다. 그것은 아주 간단한 코드입니다하지만 난 EnableIfHasFooMethod 클래스의 전문성에 대한 예상대로 decltype()가 작동하지 않는 이유를 이해할 수 없다 :SFINAE 정적 메서드를 검색하려면

#include <iostream> 

struct A { 
    static int Foo() { return 0; } 
}; 

template <class T, class = void> 
struct EnableIfHasFooMethod {}; 

template <class T> 
struct EnableIfHasFooMethod<T, decltype(T::Foo)> { 
    typedef void type; 
}; 

template <class T, class = void> 
struct HasFooMethod { 
    static const bool value = false; 
}; 

template <class T> 
struct HasFooMethod<T, typename EnableIfHasFooMethod<T>::type> { 
    static const bool value = true; 
}; 

int main() { 
    std::cout << HasFooMethod<A>::value << std::endl; 
    return 0; 
} 

출력이 0이지만, 1을해야합니다.

답변

3

당신은 당신은 너무 당신의 decltype()void IFF를 (경우만과)는이 반환해야

// ........................vvvv 
template <class T, class = void> 
struct EnableIfHasFooMethod {}; 

의 두 번째 유형 (void)와 일치 할 필요가 void()

template <class T> 
struct EnableIfHasFooMethod<T, decltype(T::Foo, void())> { /* ... */ }; 
// ...........................................^^^^^^^^ 

을 추가하는 것을 잊지 Foo() 회원이 T입니다. 이 경우, void 수없는 멤버 Foo (있는 경우)의 유형을 반환 decltype() 때문에

당신은

decltype(T::Foo) 

을 쓸 수 없습니다. 이 경우, decltype() 수익 적 void,하지만 당신은 그것을 원하지는 T

Foo 멤버가 그래서 솔루션

입니다 IFF에 있기 때문에

당신은

decltype(void()) 

을 쓸 수 없습니다

decltype(T::Foo , void()) 

그래서 SFINAE가 작동 할 수 있습니다. 에 Foo 회원이없고 Foo 인 경우 void을 반환합니다.

+0

전문화가 기본 템플릿 매개 변수에 맞춰져 있다는 사실을 잊어 버렸습니다. 고맙습니다! – eXXXXXXXXXXX2

+0

그냥 쉼표 연산자를 좋아한다 – quetzalcoatl

+0

@quetzalcoatl - 그렇다. – max66