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_C++11_Enums - Fatal编程技术网

C++ 是否可以强制初始化枚举类/函数模板的所有可能枚举值?

C++ 是否可以强制初始化枚举类/函数模板的所有可能枚举值?,c++,templates,c++11,enums,C++,Templates,C++11,Enums,我有一个模板类,使用枚举类作为模板参数,在头文件中定义: // MyClass.h enum class MyEnum {FOO, BAR}; template<MyEnum T>class MyClass { void doStuff(); // ... }; //MyClass.h 枚举类MyEnum{FOO,BAR}; 模板类MyClass{ void doStuff(); // ... }; 我希望将成员函数的实际实现放在一个单独的源文件中。我知道,在这种情况下

我有一个
模板类
,使用
枚举类
作为模板参数,在头文件中定义:

// MyClass.h
enum class MyEnum {FOO, BAR};

template<MyEnum T>class MyClass {
  void doStuff();
  // ...
};
//MyClass.h
枚举类MyEnum{FOO,BAR};
模板类MyClass{
void doStuff();
// ...
};
我希望将成员函数的实际实现放在一个单独的源文件中。我知道,在这种情况下,我必须为每种情况强制初始化模板:

//MyClass.cpp
template<MyEnum T>void MyClass<T>::doStuff() {
  // ...
}
// Implementations of other functions

template class MyClass<MyEnum::FOO>;
template class MyClass<MyEnum::BAR>;
//MyClass.cpp
templatevoid MyClass::doStuff(){
// ...
}
//其他功能的实现
模板类MyClass;
模板类MyClass;
通常,我知道我需要一个包含
enum
所有可能值的类,因此我想告诉编译器,它应该为每个可能值构建模板类,而不必明确提及每个可能值

换句话说:我想用一些自动代码替换示例中的最后两行

这有可能吗?


我也希望对模板函数而不是模板类执行同样的操作。

让编译器知道所有可能的专门化的正常方法是在同一个文件中实现它们。我想不出一个明智的方法让编译器知道模板类是为域中的每个值专门化的

如果你有一大群人,你可以考虑使用。在头文件中隔离所有案例(例如
MyEnum.h
),如下所示:

#ifndef HANDLE_ENUM_CASE(e)
#define HANDLE_ENUM_CASE(e)
#endif

HANDLE_ENUM_CASE(FOO)
HANDLE_ENUM_CASE(BAR)
// add more HANDLE_ENUM_CASE(...) expressions for every other case you have

#undef HANDLE_ENUM_CASE
在源文件中,您可以:

enum class MyEnum {
#define HANDLE_ENUM_CASE(e) e,
#include "MyEnum.h"
}

// (class declaration here)

#define HANDLE_ENUM_CASE(e) template class MyClass<MyEnum::e>;
#include "MyEnum.h"
enum类MyEnum{
#定义HANDLE_ENUM_CASE(e)e,
#包括“MyEnum.h”
}
//(此处为班级声明)
#定义HANDLE_ENUM_CASE(e)模板类MyClass;
#包括“MyEnum.h”

在过去,枚举只是整数值的自定义名称,这很简单:我们只是添加了一个MAX值作为最后一个枚举,然后用一个
进行迭代(int i=0;i您的意思是
模板类MyClass;
?我认为可以编写一个递归模板,在每次迭代中使用下一个值实例化一个模板,直到达到最后一个枚举值。但是,除非您在标头中外接每个模板实例,否则编译器将在您创建的每个翻译单元中实例化它们想要使用它们…谢谢,@Barry。相应地更正了我的问题。@Melkon:谢谢你的建议,但我想我至少需要让我的枚举可以迭代,我发现这是可能的,但不是很优雅。不过,我还是要考虑一下。你也可以将每个值作为变量模板传递……在这种情况下,你应该编写它明确地说。像这样:实例化;这可能比你应该一个一个地实例化它们要好一些。可能还不够好的解决方案。我不太喜欢
MyEnum.h
nuking
HANDLE\u ENUM\u CASE
,但是X宏肯定是一条好路。谢谢你的解决方案,@zneak。不过,我还是接受了你的答案,而不是f或者你的陈述:“我想不出一个明智的方法[…]”。可能这是我问题的唯一正确答案。我不认为这是预期的答案。我给出它只是为了展示zneak提出的宏的可能替代方案及其后果。谢谢,@Serge_Ballesta,我注意到在某些情况下,我实际上根本不需要使用模板,可以简化为函数参数(就像您在构造函数中所做的那样)。但是,我还有一些函数,其中返回类型实际上依赖于模板参数,因此您的解决方案无法在那里工作。@user2296653:因此我无法想象除了宏以外的任何东西:-)
namespace MyEnum {

    typedef int MyEnum_t;
    enum MyEnum : MyEnum_t  { FOO, BAR, MAX };
}

class MyClass {
    MyEnum::MyEnum_t T;
public:
    MyClass(MyEnum::MyEnum_t t): T(t) {}
    void doStuff() {
        std::cout << T << std::endl;
    }
};
for(MyEnum::MyEnum_t e=0; e<MyEnum::MAX; e++) {
    MyClass obj(e);
    obj.doStuff();
}