2012-06-30 1 views
5

내가이 멤버 함수 테스트가 있습니다SFINAE는 멤버 함수의 존재 시험 문제

template <typename T> 
struct has_member { 
    template <typename U> static true_type f(decltype(declval<U>().member()) *); 
    template <typename> static false_type f(...); 
    static const bool value = decltype(f<T>(0))::value; 
}; 

주어진 이름의 멤버 함수가 존재 할 때이 기능이 더 걸리는 과부하가있는 경우에, true로 평가 인수. 이러한 함수 및 STL 컨테이너의 경우 요소 액세스 함수 (앞, 뒤 등)를 제외하고는 올바르게 작동합니다.이 함수는 항상 false로 평가됩니다.

왜 그럴까요? 나는 mingw g ++ 4.7을 가지고있다.

+0

후행 반환 유형으로 변경하면 도움이됩니까? 'auto f (U * p) -> decltype (p-> member(), true_type()); ' – Xeo

답변

6

이러한 함수는 참조를 반환하고 참조에 대한 포인터 인 반환 값에 대한 포인터를 선언하므로 불가능합니다. 오류의 이러한 종류의 당신이 SFINAE가 실패 할 때 오류를 제공하기 위해 컴파일러를 강제하는 경우 해결하기 위해 (상대적으로) 쉽게 할 수 있고 당신은 그것을 생각 :

template <typename U> static true_type 
     f(typename remove_reference< decltype(declval<U>().member()) >::type *); 

PS :

빠른 수정 될 것 해서는 안된다.

코드에서 false_type을 주석 처리하고 true_type 유일한 옵션 인 경우 컴파일러의 오류를 참조하십시오. 무의미한 라인의 모음 사이에는 다음이 있습니다.

test.cpp:9:50: error: forming pointer to reference type 
    ‘__gnu_cxx::__alloc_traits<std::allocator<int> >::value_type& {aka int&}’ 
+0

고마워요. 나는 또한 참조를 제거하지 않고 그것을 할 방법을 알아 냈다고 생각 : 나는 두 번째 템플릿 인수로 "typename Check = decltype (declure () .front()"를 포함시키고 f 문자를 대신 전달한다. –

+0

@ AndrásKovács -이 방법이 더 좋습니다. – rodrigo