2014-12-08 3 views
4

다음 코드가 작동하지 않는 이유를 이해할 수 없습니다. 컴파일러 (gcc)는 메서드를 모두 인스턴스화하는 것으로 보이고 정수는 부호가 있거나 부호가 없으므로 항상 실패합니다. 나는 enable_if가 그것을 피하려고 여기에 있었지만.enable_if 및 상호 배타적 인 메서드

질문 : 왜 컴파일 오류입니까, 어떻게 피할 수 있습니까?

using namespace boost; // or std as you want 

template<typename T> 
struct test { 
    // if signed 
    template< typename enable_if 
         < is_signed<T> 
         , int 
         >:: type = 0 
      > 
    test &operator<<=(int value) 
    {} 

    // if unsigned 
    template< typename enable_if 
         < is_unsigned<T> 
         , int 
         >:: type = 0 
      > 
    test &operator<<=(int value) 
    {} 
}; 

void foo() 
{ 
    test<int> x; 
    x << 1;   // COMPILE ERROR no type named 'type' in struct enable_if<unsigned> etc. 
    test<unsigned> y; 
    y << 1;   // COMPILE ERROR no type named 'type' in struct enable_if<int> etc. 
} 
+2

"작동하지 않음"을 정의하십시오. 무슨 일이야? 당신이 원했던 것과 어떻게 다른가요? 우리는 자신의 입장에 의해 목표를 대표하지 않는 코드 조각으로부터 당신의 의도를 마술처럼 신성하게 묘사 할 수는 없습니다. –

+0

추가됨 ... '중복은'두 가지 방법을 모두 구현하는 것 같습니다 ... ' – syp

+0

전혀 "중복"하지 않습니다. 우리는 과학자입니다. _precision_ 및 _specifics_ 및 _data_를 평가합니다. "두 가지 방법을 모두 구현 한 것 같습니다."그런 것은 아닙니다! –

답변

5

SFINAE 단지에 적용 할 수있는 immediate context (SFINAE = SFIICINAE는 즉시 상황에서 대체 실패 오류되지 않음) :

§14.8.2 [temp.deduct]/P8 :

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure.

멤버 함수의 선언에서 클래스 템플릿 매개 변수의 대체는 즉시 상황이 아니며, 실패 하드 오류가 발생합니다.

당신도 유형에 따라 전체 클래스를 부분적으로 전문 또는 대체 오류가 소프트 오류가 발생할 수 있도록, 멤버 함수 템플릿 자체에 템플릿 매개 변수를 추가하여 즉각적인 상황에 맞는 자신을 소개 할 수 있습니다 :

template <typename U = T, typename std::enable_if<std::is_signed<U>{}, int>::type = 0> 
test &operator<<=(int value) 
{ return *this; } 

template <typename U = T, typename std::enable_if<std::is_unsigned<U>{}, int>::type = 0> 
test &operator<<=(int value) 
{ return *this; }