1

템플릿 전문화 부분 ("테스트 2"를 인쇄하려고 시도하는 부분)을 제거하면 코드가 잘 컴파일되지만 외부 사용자에게 깨끗하게 보이는 다른 코드 경로를 실행하는 특별한 경우가 있습니다.C++ 템플릿 전문화 : 컴파일 오류 : "형식이 아닙니다."

#include <iostream> 

using namespace std; 

struct SpecialType {}; 

template<typename A , typename B = SpecialType> 
class Test 
{ 
public: 
    class TestInner 
    { 
    public: 
     TestInner& operator*(); 
    }; 
}; 

template<typename A , typename B> 
typename Test<A , B>::TestInner& Test<A , B>::TestInner::operator*() 
{ 
    cout << "Test 1" << endl; 
    return *this; 
} 

// If the following is removed, everything compiles/works, but I want this alternate code path: 
template<typename A> 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
{ 
    cout << "Test 2" << endl; 
    return *this; 
} 

int main() 
{ 
    Test<int , SpecialType>::TestInner test; 
    *test; 

    return 0; 
} 

내가 뭘 잘못하고 있니?

편집 : 그런데 컴파일러 오류가 읽

main.cpp:26:44: error: 'Test<A, SpecialType>::TestInner' is not a type 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
              ^
main.cpp:26:89: error: invalid use of dependent type 'typename Test<A, SpecialType>::TestInner' 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
                         ^

답변

7

는 전문 클래스의 선언을 추가

template<typename A> 
class Test<A, SpecialType> 
{ 
public: 
    class TestInner 
    { 
    public: 
     TestInner& operator*(); 
    }; 
}; 

문제입니다 당신이 전문화에 대한 멤버를 정의하는 것이 그 선언되지 않았습니다. 템플릿이있는 클래스의 특수화는 일반화 된 템플릿과 멤버 또는 메서드를 공유하지 않으므로 일반화 된 템플릿의 선언은 해당 템플릿 클래스의 특수화 선언으로 사용되지 않습니다.

template <class T> 
class Foo { 
    void GeneralFunction(T x); 
} 

및 특성화 :

이 고려

여기
template <> 
class Foo<int> { 
    void SpecialisedFunction(int x); 
} 

, Foo</*anything except int*/>Foo<int> 반면 GeneralFunction는 단지 그 방법에만 SpecialisedFunction 방법이있다. 같은 논리에 의해

,이 또한 허용된다 :

template<> 
class Foo<float> { 
    float GeneralFunction; //here GeneralFunction is a data member, not a method. 
} 

긴 이야기의 짧은 당신은 당신에게 전문화를 선언해야합니다.

+0

감사합니다. 빠른 후속 질문 : 클래스 에 다른 기능이 있다면, 나머지 기능을 Test 로 상속 할 수있는 깨끗한 방법이 있습니까? 대량 코드 중복을 피하려고합니다. – Jonathan

+0

@Jonathan 내가 아는 한 템플릿 전문화 만 사용하면됩니다. 상속을 혼합하여 무언가를 얻을 수 있습니다. – bolov

+0

@Jonathan은 약간의 연구를 수행했습니다. 원하는 것은 'Curiously Recurring Template Pattern'을 사용하는 것입니다. http://stackoverflow.com/questions/6220337/code-duplication-and-template-specialization-when-the-specialized-function-has http://stackoverflow.com/questions/2757816/class-template-specializations-을 참조하십시오. with-shared-functionality – bolov