如何在编译时从字符串文字生成整数?
在 C++ 中,是否可以仅使用编译时设施从字符串文字生成整数?
例如,如果我们只有文字“6”,是否有某种方法可以将其用作模板参数,例如 std::array
?
我了解基于 constexpr 的技术,例如:
template <int N> constexpr char get_char(const char s[N], int n) {
return s[n];
}
但是 constexpr 在大多数编译器上尚未准备就绪,因此我正在寻找可能使用宏和 TMP 的解决方案。
这只是为了实验,所以疯狂的想法是受欢迎的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
显然 gcc 允许
"abcd"[3]
被解释为'd'
,这允许它工作(至少在 g++-4.6 和 4.7 上):但它不会' t 在 clang 上编译,它表示“‘const char’类型的非类型模板参数不是整型常量表达式”。
它真正做的是将字符串文字
"1234567"
分解为字符文字列表'1', '2', '3', '4', '5', “6”、“7”。 然后调用实例化
将列表转换为整数 1234567。 string → char 文字步骤可能涉及非标准行为,这些行为可能无法在 g++ 之外工作(即比
constexpr
☺ 更糟糕),但是GetIntegerTemplate<...>::value
是可移植的。Apparently gcc allows
"abcd"[3]
be interpreted as'd'
, which allows this to work (at least on g++-4.6 and 4.7):But it won't compile on clang, which says "non-type template argument of type 'const char' is not an integral constant expression".
What it really does is to break down the string literal
"1234567"
into a list of character literals'1', '2', '3', '4', '5', '6', '7'
. The instantiationis then invoked to turn the list into an integer 1234567. The string → char literal step may involve non-standard behavior which may not work outside of g++ (i.e. worse than
constexpr
☺), but thatGetIntegerTemplate<...>::value
is portable.(转发自我的另一个答案)
如果您不介意更改您的概念定义来自eg的“字符串文字”
"425897"
改为'4258','97'
,然后就可以使用 Boost。MPL 的boost::mpl::string
< /a> 来完成此操作:用法如下:
实现了对负数的支持,但未实现对溢出检测的支持(但您的编译器可能会发出警告)。
(Reposting from another answer of mine)
If you don't mind changing your conceptual definition of 'string literal' from e.g.
"425897"
to'4258','97'
, then you can use Boost.MPL'sboost::mpl::string<>
to accomplish this:Usage would look like:
Support for negative numbers is implemented, support for overflow detection is not (but your compiler will probably give a warning).
或许?
Maybe?
我不确定这是否可能,但这是你可以尝试的事情。
您可以将字符数字的值递减“0”以获得该数值。
就像:
这可以解决你一位数的问题。
为了解决一个多位数字(如“12345”),您必须循环所有数字并对结果求和(每个数字乘以 10^pos)。
这在执行时很容易做到,但在编译时就不那么简单了。
“编译时递归”可能是你的朋友。老实说,我想不出任何使用它的解决方案,但你可能会找到一个。
祝你好运!
I am not sure if it is possible, but that is something you could try.
You can decrement the value of a character digit by '0' to obtain that value in numericals.
Like:
That would solve your problem for one digit.
For you to solve a number with many digits (like "12345"), you would have to loop all the digits and sum the results (each one multiplied by 10^pos).
That would be easy to do in execution time, but in compile time it is not that simple.
"compile time recursion" may be your friend here. To be honest, I couldn't think in any solution using it, but you might find one.
Good luck!