Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用枚举作为模板参数_C++_Templates_Inheritance - Fatal编程技术网

C++ 使用枚举作为模板参数

C++ 使用枚举作为模板参数,c++,templates,inheritance,C++,Templates,Inheritance,我想使用一个模板类为一些非常相似的子类提供一些公共功能。唯一的变化是每个应用程序使用的枚举 这是父类 template<typename T> class E_EnumerationBase : public SimpleElement { public: E_EnumerationBase(); virtual bool setValue(QString choice); virtual T getState(); protected: T sta

我想使用一个模板类为一些非常相似的子类提供一些公共功能。唯一的变化是每个应用程序使用的枚举

这是父类

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;
}
链接器正在抛出此错误:

e_tableevent.cpp:6: error: undefined reference to `E_EnumerationBase<TableEventEnum>::E_EnumerationBase()'
e_tableevent.cpp:6:错误:未定义对“e_EnumerationBase::e_EnumerationBase()的引用”

枚举可以用作这样的模板的参数吗?

枚举可以是模板参数,其方式与ints完全相同

enum Enum { ALPHA, BETA };

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

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

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

该语法适用于值参数,就像适用于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
enum Foo{Bar,Frob};
模板结构Boom{};//主模板
模板结构Boom{};//全班专业化
...
模板void Boom::somefun(){}//单个成员的专门化

不能将模板函数的定义移动到单独的源文件中

在那里它根本不会被编译,因为模板不能被编译,只有模板实例可以

单独文件中的代码没有得到编译,这就是为什么实际上没有
E_EnumerationBase::E_EnumerationBase()
的定义。这就是为什么会出现链接器错误


只需将所有模板代码移到标题中

仅供参考,就像您使用Qt一样:只需看看
Q_ENUM
QMetaEnum
QMetaEnum::fromType
。这些可以方便地初始化字典。

我的坏习惯。包括构造函数和方法的实现。模板中的枚举是否作为值参数处理?我想将它用作一个类型。如果您想用
Foo
实例化
Foo
,那么无论
MyType
是类、枚举还是任何其他类型都可以。您还可以使用
Foo
实例化
Foo
,这也可以。当然,前提是替代是有意义的。如果(i)未显示用作模板参数的枚举,则实现不应写入
。这仅显示将枚举转换为int。现在(C++11)是否也可以使用
enum类
?“编译器引发此错误:”否,链接器正在抛出该错误。您的构造函数定义在头文件中吗?否,该定义在单独的源文件中。错误显示在链接上。您是否建议枚举用于其值而不是作为类型使用?主要是,我试图限制哈希表中的值。“除非你认真理解模板,否则不要编写严肃的模板代码”-这有点自大。鼓励反馈会更有帮助。@dlchambers:这不是故意的,你是对的。我完全删除了该部分。那里的[enum]根本不会被编译”-枚举本身不会被编译。它们不会占用类中的任何空间。这与静态int形成对比,静态int需要定义并导致分配。
enum Enum { ALPHA, BETA };

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

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

class Bar : public Foo <BETA> {
    // OK
}
struct Foo {
    Foo ();
}
int main () {
    Foo foo;
}
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