2012-11-15 3 views
7

부분 전문화를위한 정적 변수를 어떻게 초기화해야합니까?C++ 부분 템플릿 전문의 정적 변수를 초기화하는 방법

template <bool A=true, bool B=false> 
struct from { 
    const static std::string value; 
}; 

// no specialization - works 
template <bool A, bool B> 
const std::string from<A, B>::value = ""; 

// partial specialization - does not compile - 
// Error: template argument list following class template name must list parameters in the order used in template parameter list 
// Error: from<A,B>' : too few template arguments 
template <bool B> 
const std::string from<true, B>::value = ""; 

// full specialization - works 
const std::string from<false, true>::value = ""; 

왜 부분 작동하지 않습니까?

편집 : 나는 나는 그것이 나 정적 변수를 초기화 할 수 전에 부분 특수화에 대한 선언을 반복해야 Partial template specialization for initialization of static data members of template classes

기반으로하는 솔루션을 발견 : 다시

template <bool B> 
struct from<true, B> { 
    const static std::string value; 
}; 

을, 질문은 왜 ?

+0

어떤 컴파일러입니까? [g ++ 4.3.4] (http://ideone.com/jM6sIb)에서 마지막 하나가 작동하지 않습니다. – didierc

+0

전체 클래스 템플릿을 전문화하지 않아도됩니까? 나는 명백한 (= 완전한) 전문화 만이 회원들에게 허용된다고 생각한다. –

+0

컴파일러는 VS2010 –

답변

3

멤버를 부분적으로 특수화하는 것은 함수 또는 정적 데이터 이건간에 클래스 템플릿 자체를 부분적으로 특수화하지 않으면 허용되지 않습니다.

즉, 클래스 템플릿도 특수화해야합니다. 그래서 다음과 같은 작업을해야합니다 : 또한

//partial specialization of class template 
template <bool B> 
struct from<true, B> { 
    const static std::string value; 
}; 

//now you can do this!  
template <bool B> 
const std::string from<true, B>::value = "" 

, 이것은 컴파일되지 않습니다 (당신이 컴파일 시도?) :

// full specialization - works (SORRY, IT WILL NOT WORK!) 
const std::string from<false, true>::value = ""; //this should be an error 

당신이 작성했습니다 :

// full specialization 
template<> //<---- this is important! 
const std::string from<false, true>::value = "" 
+0

입니다. 내 목표는 if-the-else 문을 템플릿으로 대체하는 것입니다. 이 특정 시나리오에서 정적 변수를 사용하는 것은 문제가 있다는 것을 알았습니다. 이 문제를 해결할 방법을 권장 하시겠습니까? 템플릿 매개 변수 값을 기반으로 문자열을 선택하고 싶습니다. –

+0

당신은 나를 때렸어. – didierc

+0

@CandyChiu : 대신 array/map 대신 문자열을 사용 하시겠습니까? 또는 클래스 템플릿에서 멤버 함수를 사용하여 템플릿 인수의 값에 따라 다른 값을 반환 할 수 있습니다. – Nawaz

2

여기를 템플릿의 완전한 전문화.

#include <string> 
#include <iostream> 

template <bool A=true, bool B=false> 
struct from { 
    const static std::string value; 
}; 

// no specialization - works 
template <bool A, bool B> 
const std::string from<A, B>::value = "no specialization"; 

// full specialization, note the empty template parameter list 
template <> 
const std::string from<true, true>::value = "<true,true> specialization"; 


int main() { 
    std::cout << from<false, false>::value << std::endl; 
    std::cout << from<true, true>::value << std::endl; 
} 

부분을 올바르게 정의하는 방법을 찾았습니다.

부분적으로 작동하지 않는 이유는 정적 필드에 대한 초기화를 제공하기 전에 구조 유형을 선언해야하기 때문입니다. 부분 전문화는 자체적 인 템플릿이며 정의가 필요합니다.

전체 전문화는 실제로 초기 템플릿의 유형 인스턴스이므로 별도로 정의 할 필요가 없습니다.

관련 문제