2012-06-15 2 views
26

정수 및/또는 이중에 대한 특정 기능이 필요한 입력 검사기를 구축 중입니다 (예 : 'isPrime'은 정수에서만 사용할 수 있어야 함).std :: enable_if : 매개 변수 대 템플릿 매개 변수

나는 그것이 완벽하게 작동하고 매개 변수로 enable_if을 사용하고있는 경우 : 내가 템플릿 paramater로 사용하고있는 경우 (http://en.cppreference.com/w/cpp/types/enable_if에서 입증 된 바와 같이)

template <class T> 
class check 
{ 
public: 
    template< class U = T, class = typename std::enable_if<std::is_same<U, int>::value>::type > 
    inline static U readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T, class = typename std::enable_if<std::is_same<U, double>::value>::type > 
    inline static U readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

다음

template <class T> 
class check 
{ 
public: 
    template< class U = T> 
    inline static U readVal(typename std::enable_if<std::is_same<U, int>::value >::type* = 0) 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T> 
    inline static U readVal(typename std::enable_if<std::is_same<U, double>::value >::type* = 0) 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

을하지만 다음 오류가 있습니다 :

error: ‘template<class T> template<class U, class> static U check::readVal()’ cannot be overloaded 
error: with ‘template<class T> template<class U, class> static U check::readVal()’ 

두 번째 버전에서는 무엇이 잘못 되었습니까.

+0

아마도 무관하지만 VS2010에서 나는 기본 템플릿 인수가 단지 클래스 템플릿에 허용되기 때문에 그렇게 할 수 없다 -이 현학적이지만'inline' 키워드에 나는 g ++ – David

+2

모르는 멤버 메소드 또는 템플릿이 필요하지 않으며 확실히 템플릿 인 멤버가 아닙니다 ;-) – AJG85

답변

31

기본 템플릿 인수는 템플릿 서명의 일부가 아니므로 두 템플릿 모두 동일한 템플릿을 두 번 정의하려고합니다.). 그러나 매개 변수 유형은 서명의 일부입니다. 그래서 당신은 할 수

template <class T> 
class check 
{ 
public: 
    template< class U = T, 
      typename std::enable_if<std::is_same<U, int>::value, int>::type = 0> 
    inline static U readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T, 
      typename std::enable_if<std::is_same<U, double>::value, int>::type = 0> 
    inline static U readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 
+1

+1, 다른 방법보다 훨씬 깨끗해 보입니다. – ildjarn

+0

아주 똑똑한 해결책! – plasmacel

+1

기본 유형 템플릿 매개 변수 (기본 유형을 가짐)는 템플릿 서명에 포함되지 않지만 기본 유형이 아닌 템플릿 매개 변수 (기본 상수 적분 값을 가짐)는입니다. 그 맞습니까? – Alan

7

문제는 컴파일러에서 동일한 메서드 (동일한 경우)와 동일한 반환 값을 포함하는 동일한 메서드의 2 오버로드를 확인한다는 것입니다. 그러한 정의를 제공 할 수는 없습니다. 이 작업을 수행하는 가장 깨끗한 방법은 함수의 반환 값에 SFINAE을 사용하는 것입니다

template <class T> 
class check 
{ 
public: 
    template< class U = T> 
    static typename std::enable_if<std::is_same<U, int>::value, U>::type readVal() 
    { 
     return BuffCheck.getInt(); 
    } 

    template< class U = T> 
    static typename std::enable_if<std::is_same<U, double>::value, U>::type readVal() 
    { 
     return BuffCheck.getDouble(); 
    } 
}; 

그런 식으로, 당신은 2 개의 다른 과부하를 제공하고 있습니다. 하나는 int를 반환하고 다른 하나는 double을 반환하며 특정 T를 사용하여 하나만 인스턴스화 할 수 있습니다.