我想使用模板类为一些非常相似的子类提供一些常用功能。唯一的变化是每个使用的枚举。
这是父类
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()'
枚举可以用作这样的模板的参数吗?
答案 0 :(得分:30)
枚举可以是模板参数,与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;
}
答案 1 :(得分:8)
语法适用于值参数,就像typename参数一样。基本上,您只需将typename
替换为enum
的名称:
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
答案 2 :(得分:0)
您无法将模板功能的定义移动到单独的源文件中。
根本不会编译,因为模板无法编译,只有模板实例可以。
您的单独文件中的代码未被编译,这就是您实际上没有E_EnumerationBase<TableEventEnum>::E_EnumerationBase()
定义的原因。这就是你得到链接器错误的原因。
只需将所有模板代码移到标题中即可。
答案 3 :(得分:0)
仅供参考,因为您似乎使用Qt:只需查看Q_ENUM
,QMetaEnum
和QMetaEnum::fromType
即可。这些可能很方便初始化你的字典。