sla*_*ppy 14 c++ templates string-literals c-preprocessor
在C++中,是否可以仅使用编译时工具从字符串文字生成整数?
例如,如果我们只有文字"6",有没有办法将它用作模板参数,比如std::array<GET_INTEGER("6")> a;?
我知道constexpr基于技术的技术,例如:
template <int N> constexpr char get_char(const char s[N], int n) {
return s[n];
}
Run Code Online (Sandbox Code Playgroud)
但是constexpr大多数编译器还没有准备好,所以我正在寻找可能使用宏和TMP的解决方案.
这只是为了实验,所以欢迎疯狂的想法.
显然 gcc 允许"abcd"[3]解释为\'d\',这允许它工作(至少在 g++-4.6 和 4.7 上):
#include <boost/preprocessor/repetition/enum.hpp>\n\ntemplate <const char... characters>\nstruct GetIntegerTemplate;\n\ntemplate <const char head, const char... rest>\nstruct GetIntegerTemplate<head, rest...>\n{\n typedef GetIntegerTemplate<rest...> Prev;\n enum\n {\n power = Prev::power * 10,\n value = (head - \'0\') * Prev::power + Prev::value\n };\n};\n\ntemplate <>\nstruct GetIntegerTemplate<>\n{\n enum\n {\n power = 1,\n value = 0\n };\n};\n\n#define GET_NTH_CHARACTER(z, n, data) data[n]\n#define GET_INTEGER(length, the_string) GetIntegerTemplate<BOOST_PP_ENUM(length, GET_NTH_CHARACTER, the_string)>::value\n\nint main()\n{\n static_assert(GET_INTEGER(7, "1234567") == 1234567, "oops");\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但它不会在 clang 上编译,它表示“\'const char\' 类型的非类型模板参数不是整数常量表达式”。
\n\n它真正所做的是将字符串文字分解"1234567"为字符文字列表\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\'。实例化
GetIntegerTemplate<\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\'>::value\nRun Code Online (Sandbox Code Playgroud)\n\n然后调用将列表转换为整数 1234567。字符串 \xe2\x86\x92 字符文字步骤可能涉及非标准行为,该行为可能无法在 g++ 之外工作(即比constexpr\xe2\x98\xba 更糟糕),但是GetIntegerTemplate<...>::value是便携式的。