我正在尝试做这样的事情:
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) { ... }
};
我想按如下方式使用它:
enum test_enum {value_a, value_b};
struct test_enum_converter : public enum_converter<
test_enum,
{value_a, value_b},
{"a", "b"}> {};
海湾合作委员会告诉我:
class std::initializer_list<_Tp> is not a valid type
for a template constant parameter.
向该类型添加const
不会改变任何内容。有解决方法或类似的解决方案吗?
答案 0 :(得分:2)
只允许使用整数类型,枚举,指针和引用作为非类型模板参数。 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");
}
修改强>
这是一个无实例的替代方案:
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;
};
在使用课程之前,只需致电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"});
}
答案 1 :(得分:1)
指针只能是模板参数,如果它们是常量表达式,即具有extern链接的对象的地址。以下代码有效,但是您的电话是否值得:
typedef char const * charptype;
template <int, charptype> struct item;
template <typename ...> struct econv
{
static constexpr charptype convert(int) { return nullptr; }
};
template <int I, charptype S, typename ...Tail>
struct econv<item<I, S>, Tail...>
{
static constexpr charptype convert(int i)
{
return i == I ? S : econv<Tail...>::convert(i);
}
};
#include <iostream>
extern char const Hello[] = "Hello";
extern char const World[] = "World";
int main()
{
std::cout << econv< item<1, Hello>
, item<2, World> >::convert(2)
<< "\n";
}
通过将字符串放入匿名命名空间并使用一些帮助程序宏,这种方法可能会被清理一下,看起来很容易呈现。