2012-04-04 3 views
5

을 수행하여을 전문화 템플릿

template <int n> 
void f(){...}; 

은 내가 n의 특정 값을 전문으로 할 수 있습니다 알고있는 템플릿을 감안할 때 :

template <> 
void f<2>(){...}; 

을하지만, 나를 수있는 방법이있다 모든 긍정적 인 내용으로 전문화하기 위해 n?

나는 다음과 같은

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

을하고 생각 그래서 n<0이 코드가 잘못 컴파일러는 이전 정의에 의존한다. 불행히도 내가 얻는 것은 redefinition of 'void f<n>()' 오류입니다.

참고 : 표준에서 지원되지 않는 것 같습니다. 나는이 효과를 얻기 위해 어떤 방법 (어쩌면 어떤 템플릿 메타 프로그래밍)이 없는지 묻고있다.

답변

13

한 가지 옵션은 다른 수준의 간접 참조를 사용하는 것입니다. 두 개의 인수를 취하는 보조 템플릿을 정의하십시오. nbooln이 음수인지 여부를 나타내고 n이 음수 일 때 해당 템플릿을 특수화합니다. 그런 다음 f 함수가 올바른 인수를 사용하여 템플릿을 인스턴스화하게하십시오. 예를 들어

:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

또 다른 옵션은 SFINAE overloading 및 C++ (11) (또는 부스트의 동급)에서 std::enable_if 템플릿 클래스를 사용하는 것입니다; 올바른 버전은 항상 호출 할 수 있도록 n는 적절한 기호가있는 경우

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

각 기능

은 오버로드 확인에 사용할 수 있습니다.

희망이 도움이됩니다.

+5

Matter of style,하지만 나는 반환 타입에'enable_if'를 두는 것을 선호합니다. 그래서 혼란스러운 것들 (사용자와 함수의 타입)에 매달린 매개 변수가 없습니다. – GManNickG