Vin*_*ent 7 c++ templates template-meta-programming user-defined-literals c++14
目前,只有双打可以在用户定义的文字中生成字符模板:
template <char...> double operator "" _x();
// Later
1.3_x; // OK
"1.3"_y; // C++14 does not allow a _y user-
// defined operator to parse that as a template of chars
Run Code Online (Sandbox Code Playgroud)
有没有一种聪明的方法来std::integer_sequence使用用户定义的文字生成字符.换句话说,代码是什么,_y(const char*, std::size_t)以便我最终得到一个std::integer_sequence<char, '1', '.', '3'>?
此时,我们能(可移植地)做的最好的事情就是使用宏技巧,如所示vtmpl::string。基本上,我们创建一个访问列表,例如
"abcd" -> {(0 < sizeof "abcd"? "abcd"[0] : 0), (1 < sizeof "abcd"? "abcd"[1] : 0), ...}\nRun Code Online (Sandbox Code Playgroud)\n\n我们修剪 \xe2\x80\xa6 以获得所需的结果。
\n\n第一步很容易通过 完成BOOST_PP_ENUM,尽管递归宏也很好(定义来自此处):
#define VTMPL_SPLIT_1(s, x, m) m(s, x)\n#define VTMPL_SPLIT_4(s, x, m) VTMPL_SPLIT_1 (s, x, m), VTMPL_SPLIT_1 (s, x+1 , m), VTMPL_SPLIT_1 (s, x+2 , m), VTMPL_SPLIT_1 (s, x+3 , m)\n#define VTMPL_SPLIT_16(s, x, m) VTMPL_SPLIT_4 (s, x, m), VTMPL_SPLIT_4 (s, x+4 , m), VTMPL_SPLIT_4 (s, x+8 , m), VTMPL_SPLIT_4 (s, x+12 , m)\n#define VTMPL_SPLIT_64(s, x, m) VTMPL_SPLIT_16 (s, x, m), VTMPL_SPLIT_16 (s, x+16 , m), VTMPL_SPLIT_16 (s, x+32 , m), VTMPL_SPLIT_16 (s, x+48 , m)\n#define VTMPL_SPLIT_256(s, x, m) VTMPL_SPLIT_64 (s, x, m), VTMPL_SPLIT_64 (s, x+64 , m), VTMPL_SPLIT_64 (s, x+128, m), VTMPL_SPLIT_64 (s, x+194, m)\n#define VTMPL_SPLIT_1024(s, x, m) VTMPL_SPLIT_256(s, x, m), VTMPL_SPLIT_256(s, x+256, m), VTMPL_SPLIT_256(s, x+512, m), VTMPL_SPLIT_256(s, x+768, m)\nRun Code Online (Sandbox Code Playgroud)\n\n上面的用法看起来像这样(包括修剪):
\n\n#define VTMPL_STRING_IMPL(str, n) vtmpl::rtrim<vtmpl::value_list<decltype(*str), VTMPL_SPLIT_##n(str, 0, VTMPL_ARRAY_SPLIT)>>::type\n#\n#define VTMPL_STRING(str) VTMPL_STRING_IMPL(str, 64 )\nRun Code Online (Sandbox Code Playgroud)\n\n其中rtrim定义在algorithms.hxx.