C++ 使用枚举作为模板参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9116267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using an enumeration as a template parameter
提问by IslandCow
I would like to use a template class to provide some common functionality to some child classes that are very similar. The only variation is the enumeration that each uses.
我想使用模板类为一些非常相似的子类提供一些通用功能。唯一的变化是每个使用的枚举。
This is the parent class
这是父类
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;
}
This is one of the children
这是其中一个孩子
enum TableEventEnum {
NO_VALUE = 0,
ATTRACT = 1,
OPEN = 2,
CLOSED = 3
};
class E_TableEvent : public E_EnumerationBase<enum TableEventEnum>
{
public:
E_TableEvent();
};
This is the constructor
这是构造函数
E_TableEvent::E_TableEvent()
{
state = NO_VALUE;
dictionary.insert("attract", ATTRACT);
dictionary.insert("open", OPEN);
dictionary.insert("closed", CLOSED);
}
The linker is throwing this error:
链接器抛出此错误:
e_tableevent.cpp:6: error: undefined reference to `E_EnumerationBase<TableEventEnum>::E_EnumerationBase()'
Can an enumeration be used as the parameter to a template like this?
枚举可以用作这样的模板的参数吗?
回答by spraff
Enumerations can be template parameters in exactly the same way that ints can.
枚举可以以与 int 完全相同的方式作为模板参数。
enum Enum { ALPHA, BETA };
template <Enum E> class Foo {
// ...
};
template <> void Foo <ALPHA> :: foo () {
// specialise
}
class Bar : public Foo <BETA> {
// OK
}
But you simply haven't provided a definition for E_EnumerationBase::E_EnumerationBase()
但你根本没有提供定义 E_EnumerationBase::E_EnumerationBase()
This isn't a problem with templates or inheritence. It's the same as if you written this:
这不是模板或继承的问题。就像你写这个一样:
struct Foo {
Foo ();
}
int main () {
Foo foo;
}
回答by Sebastian Mach
The syntax goes for value arguments like it is for typename arguments. Basically, you just replace typename
with the name of your enum
:
语法适用于值参数,就像适用于 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
回答by Lol4t0
You cannot move definition of template function to separate source file.
您不能将模板函数的定义移动到单独的源文件中。
There it wouldn't be compiled at all, because templates can't be compiled, only template instances can.
在那里它根本不会被编译,因为模板不能被编译,只有模板实例可以。
Your code in separate file isn't get compiled, that's why you actually have no definition for E_EnumerationBase<TableEventEnum>::E_EnumerationBase()
. That's why you get linker error.
您在单独文件中的代码没有被编译,这就是为什么您实际上没有E_EnumerationBase<TableEventEnum>::E_EnumerationBase()
. 这就是您收到链接器错误的原因。
Just move all template code to your header.
只需将所有模板代码移动到您的标题。
回答by Kamajii
Just for reference, as you seem to use Qt: Just have a look at Q_ENUM
, QMetaEnum
and QMetaEnum::fromType
. These may come handy to initialize your dictionary.
仅供参考,因为您似乎在使用 Qt:只需看看Q_ENUM
,QMetaEnum
和QMetaEnum::fromType
。这些可能会派上用场来初始化您的字典。