映射枚举值为C 中的模板参数

Map enum value to template argument in C++

本文关键字:参数 枚举 映射      更新时间:2023-10-16

我有一个带有几个成员的枚举类。枚举的目的是在运行时编码原始类型(例如int,long,float,...),以便例如在数据库中存储此信息。同时,也存在许多模板来处理原始类型的类。

问题:我想从这种模板类创建一个对象,给定一个不是常数的枚举值。这可以比在枚举值上创建长长的开关以更清洁,更可扩展的方式(或与eNum值(int)对type的动态映射回答中所提出的映射进行基本相同)?<<<<<<<<<<<</p>

这是我一直在尝试希望模板类型推理可以起作用的东西,但是它无法编译(例如,可以在此处检查: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. ,除非是constconstexpr

  4. ,您不能将value用作模板参数

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

#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();
}