- GCC

2014-11-04 3 views
2

에서 MSVC의 작품, 컴파일 오류가 I이이 아래로 비등 일부 코드 :- GCC

#include <type_traits> 

struct CByteArray {}; 

struct CIODevice { 
    template <typename T> 
    CIODevice& operator<< (T value) 
    { 
     static_assert(std::is_pod<T>::value, "This method is only intended for POD types"); 
     return *this; 
    } 

    template <> 
    CIODevice& operator<< (CByteArray data) 
    { 
     return *this; 
    } 

    template <typename T> 
    CIODevice& operator>> (T& value) 
    { 
     static_assert(std::is_pod<T>::value, "This method is only intended for POD types"); 
     return *this; 
    } 
}; 

int main() 
{ 
    CIODevice device; 
    int i = 0; 
    device << i; 
    device >> i; 
    return 0; 
} 

그것은 MSVC에서 컴파일하지만 GCC 내가이 얻을 :

prog.cpp:13:12: error: explicit specialization in non-namespace scope ‘struct CIODevice’ 
    template <> 
      ^
prog.cpp:20:11: error: too many template-parameter-lists 
    CIODevice& operator>> (T& value) 
     ^
prog.cpp: In function ‘int main()’: 
prog.cpp:32:9: error: no match for ‘operator>>’ (operand types are ‘CIODevice’ and ‘int’) 
    device >> i; 
    ^

Live sample.

나는 그것을 얻지 못한다, 여기의 실수는 무엇인가?

+0

(BTW, SFINAE는 전체 클래스를 전문으로하는 것보다이 케이스를 처리하는보다 우아한 방법이며 크로스 플랫폼입니다. http://en.cppreference.com/w/cpp/types/enable_if를 참조하고 토끼에 오신 것을 환영합니다. 템플릿이 아닌 구멍을 사용하는 것입니다. – IdeaHat

+0

@MadScienceDreams : 저는 클래스를 전문으로하지 않고 템플릿이 아닌 클래스의 템플릿 메서드를 전문적으로 다루고 있습니다. 또한 지난 2 일 동안 (말 그대로) enable_if'를 입력 한 다음 예상대로 작동하지 않는 이유를 이해 한 다음 다른 템플릿 트릭을 사용하여 제거하십시오. 이제는 더 이상 enable_if를 사용하지 마십시오. –

+2

이것은 중복 질문이 아닙니다. 참조 된 질문은 클래스 템플릿 내에서 멤버 함수 템플릿을 특수화하는 것입니다.이 템플릿 클래스는 명시 적으로 템플릿이 아닌 클래스에 대한 것입니다. –

답변

4

C++ 사양 § 14.7.3 (발췌); 명시 적 전문성을 선언해야한다

  • ... 클래스 또는 클래스 템플릿의
    • 멤버 함수 템플릿 ... :

      1. 다음 중 하나의 명시 적 특수화 특수한 템플릿을 둘러싸는 네임 스페이스.

      기본적으로 네임 스페이스 범위 (GCC 및 Clang에서 필요함)로 선언해야합니다.

      struct CIODevice { 
          template <typename T> 
          CIODevice& operator<< (T value) 
          { 
           static_assert(std::is_pod<T>::value, "This method is only intended for POD types"); 
           return *this; 
          } 
      
          template <typename T> 
          CIODevice& operator>> (T& value) 
          { 
           static_assert(std::is_pod<T>::value, "This method is only intended for POD types"); 
           return *this; 
          } 
      }; 
      
      template <> 
      CIODevice& CIODevice::operator<< (CByteArray data) 
      { 
          return *this; 
      } 
      

      Sample code.

  • +0

    @VioletGiraffe. 죄송합니다. 동기 부여에 아무 생각도, 좋은 지적, 이제는 당신도 왜 궁금해 물어보십시오. – Niall

    +1

    오! 나는 심지어 수업 내에서 그것을 선언하지 않고도 전문화를 정의 할 수 있다는 것을 깨닫지 못했습니다! 그 문법은 전혀 예상치 못한 일입니다. 감사. 나는 왜 그것이 이렇게 설계되었는지 궁금해. 반 직관적 인 것 같습니다. –

    +1

    @VioletGiraffe 전문화를 정의하는 것이 실제로 클래스에 추가 멤버를 추가하지는 않지만 그럴 것 같아서 그렇다고 말할 수 있습니다. 전문 분야는 다른 기능이 아니며 특정 템플릿 인수 집합에 대해 템플릿에서 기능을 만드는 방법입니다. 말하자면 템플리트의 속성입니다. – Angew

    1

    this도 참조하십시오.

    기본적으로 MSVC가 잘못되었으며 GCC가 맞습니다. 그렇게 할 수 없습니다.

    전문화 대신 오버로드를 사용하지 않는 이유는 무엇입니까? 시도 :

    template <typename T> 
    CIODevice& operator<< (T value) 
    { 
        static_assert(std::is_pod<T>::value, "This method is only intended for POD types"); 
        return *this; 
    } 
    
    // template <> // <--- Remove this 
    CIODevice& operator<< (CByteArray data) 
    { 
        return *this; 
    } 
    
    +0

    멋진 제안, 과부하의 단순함을 좋아합니다. 해상도 규칙을 약간 변경하지만 아마 더 좋을 것입니다. +1 – Niall