将枚举值映射到 C++ 中的模板参数

mis*_*sev 3 c++ enums templates c++11

我有一个有几个成员的枚举类。枚举的目标是在运行时对基本类型(例如 int、long、float 等)进行编码,以便可以将此信息存储在数据库中。同时,还存在许多针对原始类型进行模板化的类。

\n\n

问题:我想从这样的模板类创建一个对象,给定一个不是常量的枚举值。这是否可能以比在枚举值上创建长开关(或者与动态映射枚举值(int)到类型的答案中建议的映射基本相同)更干净且更具可扩展性的任何方式实现?

\n\n

这是我一直在尝试的事情,希望模板类型推断可以工作,但它无法编译(可以在此处检查,例如: http: //rextester.com/VSXR46052):

\n\n
#include <iostream>\n\nenum class Enum {\n    Int,\n    Long\n};\n\ntemplate<Enum T>\nstruct EnumToPrimitiveType;\n\ntemplate<>\nstruct EnumToPrimitiveType<Enum::Int> {\n    using type = int;\n};\n\ntemplate<>\nstruct EnumToPrimitiveType<Enum::Long> {\n    using type = long;\n};\n\ntemplate<typename T>\nclass TemplatedClass\n{\npublic:\n    TemplatedClass(T init): init{init} {}\n    void printSize() { std::cout << sizeof(init) << std::endl; }\nprivate:\n    T init;\n};\n\ntemplate<Enum T>\nauto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>\n{\n    TemplatedClass<EnumToPrimitiveType<T>::type> ret(5);\n    return ret;\n}\n\nint main()\n{\n    Enum value{Enum::Int};\n    auto tmp = makeTemplatedClass(value);\n    tmp.printSize();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译错误:

\n\n
source_file.cpp:36:27: error: expected \xe2\x80\x98)\xe2\x80\x99 before \xe2\x80\x98enumValue\xe2\x80\x99\n auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>\n                           ^\nsource_file.cpp:36:6: warning: variable templates only available with -std=c++14 or -std=gnu++14\n auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>\n      ^\nsource_file.cpp:36:38: error: expected \xe2\x80\x98;\xe2\x80\x99 before \xe2\x80\x98->\xe2\x80\x99 token\n auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>\n                                      ^\nsource_file.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nsource_file.cpp:44:16: error: \xe2\x80\x98A\xe2\x80\x99 is not a member of \xe2\x80\x98Enum\xe2\x80\x99\n     Enum value{Enum::A};\n                ^\nsource_file.cpp:45:34: error: missing template arguments before \xe2\x80\x98(\xe2\x80\x99 token\n     auto tmp = makeTemplatedClass(value);\n                                  ^\n
Run Code Online (Sandbox Code Playgroud)\n

R S*_*ahu 5

我看到的问题:

  1. 您不能使用,template<Enum T> auto makeTemplatedClass(T enumValue)因为T它不是一种类型。您需要以不同的方式使用 justtemplate<Enum T> auto makeTemplatedClass()和调用该函数。

  2. 您需要使用TemplatedClass<typename EnumToPrimitiveType<T>::type>而不是仅仅使用TemplatedClass<EnumToPrimitiveType<T>::type>. 这是必要的,因为它type是依赖类型。

  3. 除非它是 a或 ,否则不能用作value模板参数。constconstexpr

以下程序在我的桌面上编译和构建。

#include <iostream>

enum class Enum {
    Int,
    Long
};

template<Enum T>
struct EnumToPrimitiveType;

template<>
struct EnumToPrimitiveType<Enum::Int> {
    using type = int;
};

template<>
struct EnumToPrimitiveType<Enum::Long> {
    using type = long;
};

template<typename T>
class TemplatedClass
{
public:
    TemplatedClass(T init): init{init} {}
    void printSize() { std::cout << sizeof(init) << std::endl; }
private:
    T init;
};

template<Enum T>
auto makeTemplatedClass() -> TemplatedClass<typename EnumToPrimitiveType<T>::type>
{
    TemplatedClass<typename EnumToPrimitiveType<T>::type> ret(5);
    return ret;
}

int main()
{
    Enum const value{Enum::Int};
    auto tmp = makeTemplatedClass<value>();
    tmp.printSize();
}
Run Code Online (Sandbox Code Playgroud)