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

标签 c++ c++11 templates enums

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

问题:我想从这样一个模板类创建一个对象,给定一个不是常量的枚举值。与在枚举值上创建长开关(或与 Dynamic mapping of enum value (int) to type 的答案中建议的映射进行本质上相同的操作)相比,这是否有可能以任何更清洁且更具可扩展性的方式实现?

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

#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(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>
{
    TemplatedClass<EnumToPrimitiveType<T>::type> ret(5);
    return ret;
}

int main()
{
    Enum value{Enum::Int};
    auto tmp = makeTemplatedClass(value);
    tmp.printSize();
}

编译错误:

source_file.cpp:36:27: error: expected ‘)’ before ‘enumValue’
 auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>
                           ^
source_file.cpp:36:6: warning: variable templates only available with -std=c++14 or -std=gnu++14
 auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>
      ^
source_file.cpp:36:38: error: expected ‘;’ before ‘->’ token
 auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type>
                                      ^
source_file.cpp: In function ‘int main()’:
source_file.cpp:44:16: error: ‘A’ is not a member of ‘Enum’
     Enum value{Enum::A};
                ^
source_file.cpp:45:34: error: missing template arguments before ‘(’ token
     auto tmp = makeTemplatedClass(value);
                                  ^

最佳答案

我看到的问题:

  1. 您不能使用 template<Enum T> auto makeTemplatedClass(T enumValue)T不是一种类型。您只需要使用 template<Enum T> auto makeTemplatedClass()并以不同的方式调用函数。

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

  3. 您不能使用 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();
}

关于c++ - 将枚举值映射到 C++ 中的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42593311/

相关文章:

c++ - 使用 PyTorch、HElib 和 OpenCV 编译 C++ 程序时出现问题

c++ - 这段代码中 decltype 的用途是什么?

c++ - 在成员函数内的 lambda 捕获列表中使用成员变量

c++ - 没有删除运算符的 shared_ptr 内存泄漏

python - 如何使用 Flask 提供 HTML 和 JSON 内容?

c++ - 自动引用 vector ?

c++ - 从小部件的父级访问坐标

c++ - std::queue::size() 在 pop() of size() == 0 之后可以返回一个巨大的数字

c++ - 从基类指针集合中调用非虚拟成员函数?

C++ 可变参数模板产品