std::initializer_list 值作为模板参数

fly*_*lyx 5 c++ templates initializer-list

我正在尝试做这样的事情:

template<typename enumType,
         std::initializer_list<enumType> values,
         std::initializer_list<std::string> mappings>
struct enum_converter {
    enumType toEnum(const std::string& literal) { ... }
    std::string toString(const enumType value) { ... }
};
Run Code Online (Sandbox Code Playgroud)

我想按如下方式使用它:

enum test_enum {value_a, value_b};
struct test_enum_converter : public enum_converter<
        test_enum,
        {value_a, value_b},
        {"a", "b"}> {};
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会告诉我:

class std::initializer_list<_Tp> is not a valid type
for a template constant parameter.
Run Code Online (Sandbox Code Playgroud)

添加const到类型不会改变任何东西。有解决方法或类似的解决方案吗?

Rei*_*ica 3

仅允许整型、枚举、指针和引用作为非类型模板参数。std::initializer_list两者都不是。

您是否需要将值和映射作为模板参数?如何将它们设置为构造函数的普通参数,并仅保留枚举作为模板参数?

template<typename enumType>
struct enum_converter {
    enum_converter(std::initializer_list<enumType> values, std::initializer_list<std::string> mappings) : values(values), mappings(mappings)

    enumType toEnum(const std::string& literal) { ... }
    std::string toString(const enumType value) { ... }

private:
    std::initializer_list<enumType> values;
    std::initializer_list<std::string> mappings;
};

enum_converter<test_enum> test_enum_converter({...}, {...});

int main()
{
    test_enum_converter.toEnum("bla");
}
Run Code Online (Sandbox Code Playgroud)

编辑

这是一个无实例的替代方案:

template<typename enumType>
struct enum_converter {
    static init(std::initializer_list<enumType> values, std::initializer_list<std::string> mappings)
    { s_values = values; s_mappings = mappings; }

    static enumType toEnum(const std::string& literal) { ... }
    static std::string toString(const enumType value) { ... }

private:
    static std::initializer_list<enumType> s_values;
    static std::initializer_list<std::string> s_mappings;
};
Run Code Online (Sandbox Code Playgroud)

init()在使用课程之前只需调用一次即可。

如果您需要对某一特定枚举进行多个实例化,则可以向模板添加一个消歧参数,如下所示:

template <typename enumType, typename tag>
struct enum_converter { /*as before*/ };

int main()
{
  struct data_strings;
  struct user_readable_strings;
  enum_converter<test_enum, data_strings>::init({...}, {"a", "b"});
  enum_converter<test_enum, user_readable_strings>::init({...}, {"Option A", "Option B"});
}
Run Code Online (Sandbox Code Playgroud)