2013-08-30 2 views
1
template<class T> 
struct is_class_or_union 
{ 
    struct twochar { char _[2]; }; 
    template <class U> 
    static char is_class_or_union_tester(void(U::*)(void)); 
    template <class U> 
    static twochar is_class_or_union_tester(...); 
    static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); 
}; 

위의 코드는 부스트 라이브러리에서 meta_utils.hpp입니다. 부스트 코드 발췌 부분 - 이해할 수 없음

  1. is_class_or_union_tester

    static 기능 char을 반환하고 (무효 반환 아무것도지지 않습니다) 멤버 함수에 대한 포인터를 복용 것 같다. 함수 몸체는 없으며 다른 곳에서는 정의되지 않는 것처럼 보입니다. 나는 그것이 어떻게 작용하는지 그리고 무엇보다도, 기능의 목적을 이해하지 못한다.
  2. 다음 코드의 개념을 이해할 수 없습니다. static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); sizeof 연산자는 무엇입니까? 그들은 여기서 무엇을 찾으려고 노력하고 있습니까?
+0

가능한 복제본 [C++ SFINAE 예제?] (http://stackoverflow.com/questions/982808/c-sfinae-examples) – soon

+0

@peter 설명해 주셔서 감사합니다. 확실히 도움이되었습니다. 그 함수가 호출되지 않았기 때문에 (함수 정의에 대한) 링커 에러가 없었던 것일까 요? –

+0

실제로 코드가 작성되지 않았기 때문에 링커 오류가 발생하지 않았습니다. 'sizeof'는 실제로 전달 된 표현식을 실행하지 않고 결과의 유형을 파악한 다음 그 크기를 계산합니다. –

답변

3

여기에서 사용되는 기술은 가능한 후보 템플릿 간의 일치를 선택하기 위해 컴파일러에서 사용되는 기술인 SFINAE (대체 오류는 오류가 아닙니다)입니다. 특히 템플릿 매개 변수의 잘못된 대체가 그 자체가 아닌 경우 일치하는 프로세스 중에 오류가 발생했습니다. T 클래스 인 경우는 최초의 기능을 선택합니다

template <class U> 
static char is_class_or_union_tester(void(U::*)(void)); 

또는

template <class U> 
static twochar is_class_or_union_tester(...); 

사이에 선택할 수

is_class_or_union_tester<T>(0) 

이 경우 컴파일러에 대한 일치하는 항목을 찾기 위해 시도 템플릿은 클래스가 멤버 함수를 가질 수 있기 때문에 T가 공용체이면 두 번째를 선택합니다. sizeof은 함수를 실행하지 않으며 템플릿 선언의 반환 유형에서만 작동합니다. 리턴 타입이 다르다는 것과 sizeof (char)에 대한 비교가 올바른 값을 반환한다는 것을 알 수 있습니다.

+0

언어가 허용하고 사람들이 이런 종류의 메커니즘을 사용한다면 아마도 그럴 수있는 명시적인 방법이 설계되어야합니다. 이것은 매우, 매우 해커처럼 보인다. – szpanczyk

관련 문제