2009-02-01 3 views
1

템플릿 클래스 인 C_Foo <T>은 여러 가지 방법으로 특수화되어 있습니다.C++ 템플릿 클래스를 목록에 추가하기

struct Bar_Base { ... }; 
struct Bar_1 : public Bar_Base { ... }; 
struct Bar_2 : public Bar_Base { ... }; 
struct Bar_3 : public Bar_Base { ... }; 

class C_Foo<T> { ... }; 

class C_Foo_1 : public C_Foo<Bar_1> { ... }; 
class C_Foo_2 : public C_Foo<Bar_2> { ... }; 
class C_Foo_3 : public C_Foo<Bar_3> { ... }; 

그리고 인스턴스화 다음과 같이

C_Foo_1  foo1; 
C_Foo_2  foo2; 
C_Foo_3  foo3; 

나는 foo1은,에서는 foo2 및 foo3에서 수행 할 것을 C_Foo에 정의되어 모두 일반적인 작업, 세트를 가지고있다.

vector<C_Foo *> v; 
v.push_back(&foo1); 
v.push_back(&foo2); 
v.push_back(&foo3); 

하지만 컴파일러가 C_Foo에 C_Foo_1에서 이동하는 방법을 잘하지 아마도 때문에, 컴파일 오류를 얻을 : 나는 다음 시도했습니다.

이렇게 할 수 있습니까?

foo1.do_stuff(); 
foo2.do_stuff(); 
foo3.do_stuff(); 

감사를 도와 : 나는 foo1은 .. 푼을 통해 루프 수 등과 같은 상투적 인 코드를 복사하여 붙여 넣기 할 필요없이, 그들 모두에서 동일한 작업을 수행합니다.

답변

6
당신이 할 수있는

, 그 함수는 템플릿 매개 변수에 의존하지 않는 경우

// note: not a template 
class C_Foo_Common { 
public: 
    virtual void do_stuff() = 0; 
}; 

template<typename T> 
class C_Foo : public C_Foo_Common { 
    virtual void do_stuff() { 
     // do stuff... 
    } 
}; 

vector<C_Foo_Common *> v; 
v.push_back(&foo1); 
v.push_back(&foo2); 
v.push_back(&foo3); 
// now, you can iterate and call do_stuff on them. 

그러나 C_Foo_Common의 함수가 T 유형을 알아야하는 경우 (예를 들어 T에 종속 된 다른 반환 유형을 갖는 경우) 더 이상 가능하지 않습니다. C_Foo<Bar_1>C_Foo<Bar_2>과 다른 유형입니다. 차별화 된 노동 조합을 대신 사용할 수 있습니다. 사람들은 그들에 저장되어있는 것에 대해 추적하고 완전히 제네릭 :

typedef boost::variant< 
    C_Foo<Bar_1>*, C_Foo<Bar_2>*, C_Foo<Bar_3>* 
> variant_type; 
vector<variant_type> v; 
v.push_back(&foo1); 
v.push_back(&foo2); 
v.push_back(&foo3); 

변종 그것을 저장 알고, 그 안에 저장 될 수있는의 유형에 오버로드 함수를 호출 할 수 있습니다. 변종에 포함 된 내용을 얻는 방법에 대한 자세한 내용은 boost::variant 설명서를 참조하십시오.

4

C_Foo은 템플릿 매개 변수가 필요하기 때문에 C_Foo을 인스턴스화 할 수 없습니다.

당신은 다른 기본 클래스를 만들고, 일반적인 작업의 사용자 설정하는 것이 내에서 할 수 있습니다 :

class C_FooBase { ... }; 

template<typename T> 
class C_Foo<T> : public C_FooBase { ... }; 

class C_Foo_1 : public C_Foo<Bar_1> { ... }; 
class C_Foo_2 : public C_Foo<Bar_2> { ... }; 
class C_Foo_3 : public C_Foo<Bar_3> { ... }; 
2

C_Foo < T>가 클래스로 존재하지 않기 때문입니다. C_Foo < Bar1>은 실제 클래스이며 C_Foo와 아무런 관련이 없습니다. < Bar2>, 완전히 다른 클래스입니다. 템플릿은 컴파일러가 코드를 복제 할 수있는 도구이며, Java 또는 C#으로 제네릭과 같은 실제 클래스가 아닙니다. 당신은 당신이 원하는 것을 할 수없는 이유는 C_Foo < BAR1>, C_Foo < 바 2>와 C_Foo < 왈져가> 완전히 다른 클래스가 있고 공통점이 없다고 생각하여 코드를 다시 보면

는, 당신은 이해 네가 원하는대로.

strager와 마찬가지로 공용 클래스로 실제 기본 클래스를 사용하십시오.

관련 문제