2012-02-02 9 views
10

템플릿 클래스를 사용하여 매우 유사한 일부 하위 클래스에 몇 가지 공통 기능을 제공하고 싶습니다. 유일한 변형은 각각 사용하는 열거 형입니다.열거 형을 템플릿 매개 변수로 사용하기

:

template<typename T> class E_EnumerationBase : public SimpleElement 
{ 
public: 
    E_EnumerationBase(); 
    virtual bool setValue(QString choice); 
    virtual T getState(); 

protected: 
    T state; 
    QHash<QString, T> dictionary; 
}; 

template<typename T> E_EnumerationBase<T>::E_EnumerationBase() { 
    state = 0; 
} 

template<typename T> bool E_EnumerationBase<T>::setValue(QString choice) { 
    T temp; 
    temp = dictionary.value(choice, 0); 
    if (temp == 0) { 
     return false; 
    } 

    value = choice; 
    state = temp; 
    return true; 
} 

template<typename T> T E_EnumerationBase<T>::getState() { 
    return state; 
} 

이 아이들 중 하나가

enum TableEventEnum { 
    NO_VALUE = 0, 
    ATTRACT = 1, 
    OPEN = 2, 
    CLOSED = 3 
}; 

class E_TableEvent : public E_EnumerationBase<enum TableEventEnum> 
{ 
public: 
    E_TableEvent(); 
}; 

이 링커는이 오류를 던지고있다

E_TableEvent::E_TableEvent() 
{ 
    state = NO_VALUE; 
    dictionary.insert("attract", ATTRACT); 
    dictionary.insert("open", OPEN); 
    dictionary.insert("closed", CLOSED); 
} 

생성자에게있는 부모 클래스입니다

e_tableevent.cpp:6: error: undefined reference to `E_EnumerationBase<TableEventEnum>::E_EnumerationBase()' 

열거 형을이 같은 템플릿에 대한 매개 변수로 사용할 수 있습니까?

+4

"컴파일러에서이 오류가 발생합니다. *"아니요, _linker_에서 해당 오류가 발생했습니다. – ildjarn

+0

생성자 정의가 헤더 파일에 있습니까? – Lol4t0

+0

아니요, 정의는 별도의 소스 파일에 있습니다. 링크에 오류가 표시됩니다. – IslandCow

답변

18

열거 형은 int와 완전히 동일한 방식으로 템플릿 매개 변수가 될 수 있습니다.

enum Enum { ALPHA, BETA }; 

template <Enum E> class Foo { 
    // ... 
}; 

template <> void Foo <ALPHA> :: foo() { 
    // specialise 
} 

class Bar : public Foo <BETA> { 
    // OK 
} 

그러나 단순히 E_EnumerationBase::E_EnumerationBase()

이에 대한 정의를 제공하지 않은 템플릿 또는 상속 문제가 아닙니다. 다음과 같이 쓰면 같습니다.

struct Foo { 
    Foo(); 
} 
int main() { 
    Foo foo; 
} 
+0

내 잘못입니다. 생성자 및 메서드의 구현이 포함됩니다. – IslandCow

+0

[ideone.com] (http://www.ideone.com) 또는 그와 유사한 형식의 오류 만 게시 할 수 있습니까? 행 번호 등을 보는 것이 도움이 될 것입니다. 지금은'public E_EnumerationBase '이 전혀 컴파일되지 않는다고 생각합니다. – spraff

+0

_is_가 컴파일됩니다. _And links_ : http://ideone.com/Blaw9 – Lol4t0

7

구문은 typename 인수와 마찬가지로 값 인수로 사용됩니다. 기본적으로, 당신은 당신의 enum의 이름으로 typename 대체 : 당신이 심각 템플릿을 이해하지

enum Foo { Bar, Frob }; 

template <Foo F> struct Boom {}; // primary template 
template <> struct Boom<Bar> {}; // specialization of whole class 

... 

template <> void Boom<Frob>::somefun() {} // specialization of single member 

심각한 템플릿 코드를 작성하지 마십시오.


그러나, 내 진짜 추천 먼저 템플릿에 좋은 읽기를 얻을 수있을 것이다. 당신이 돈을 쓸 수 있다면, 나는 Josuttis에/Vandevoorde의 C++ 템플릿을 사용하는 것이 좋습니다 완전한 가이드에게

+1

Are 당신은 그 열거 형이 값이 아닌 형식으로 사용되고 있다고 제안합니까? 주로 해시 테이블의 값을 제한하려고합니다. – IslandCow

0

을 당신은 별도의 소스 파일에 템플릿 함수의 정의를 이동할 수 없습니다.

템플릿을 컴파일 할 수 없으므로 컴파일되지 않습니다. 템플릿 인스턴스 만 컴파일 할 수 있습니다.

별도의 파일에 코드가 컴파일되지 않기 때문에 실제로 E_EnumerationBase<TableEventEnum>::E_EnumerationBase()에 대한 정의가 없습니다. 그래서 링커 오류가 발생합니다.

모든 템플릿 코드를 헤더로 이동하십시오.

+0

* [열거 형]은 전혀 컴파일되지 않습니다 "* - Enums don 그 자체로 컴파일되지 않습니다. 그들은 수업 시간에 아무런 공간도 차지하지 않습니다. 이것은 정의를 필요로하고 할당을 발생시키는 정적 int와는 대조적입니다. – jww

0

그냥 참고로 Qt를 사용하는 것 같습니다. Q_ENUM, QMetaEnumQMetaEnum::fromType을 살펴보십시오. 사전을 초기화하는 데 유용 할 수 있습니다.

관련 문제