Khu*_*dov 7 c++ user-defined-literals c++11
我正在学习C++ 11,并对用户定义的文字感兴趣.所以我决定玩一下.有些语言的语法如下:
int n = 1000_000_000;
Run Code Online (Sandbox Code Playgroud)
我试图在C++ 11中模拟这个功能.
inline constexpr unsigned long long operator "" _000 (unsigned long long n)noexcept
{
return n * 1000;
}
inline constexpr unsigned long long operator "" _000_000 (unsigned long long n)noexcept
{
return n * 1000*1000;
}
inline constexpr unsigned long long operator "" _000_000_000 (unsigned long long n)noexcept
{
return n * 1000*1000*1000;
}
int main(){
constexpr auto i = 100_000; // instead of 100000
constexpr auto j = 23_000_000; // instead of 23000000;
}
Run Code Online (Sandbox Code Playgroud)
但对于一般情况我无法模拟它,即
auto general_case = 123_456_789; //无法编译
我的问题是"我可以使用C++ 11模拟上面的一般情况吗?".
对于目前的 C++11 版本语言中的用户定义文字来说,这是不可能的。用户定义的文字支持有限的参数格式,似乎不支持右侧参数、链接,而且存在将以 0 开头的数字表示为实际数字的问题。所以这是不行的。
您当前的方法将 _000 等定义为独立文字,因此编译器只能使用它们,而不能使用其他文字。不幸的是,它不像 is_运算符和000is 一些可以使用的参数。
但是,您可以改用字母后缀。
long long constexpr operator"" K (long double n) {
return n * 1000;
}
long long constexpr operator"" M (long double n) {
return n * 1000000;
}
long long constexpr operator"" G (long double n) {
return n * 1000000000;
}
Run Code Online (Sandbox Code Playgroud)
进而:
0.05M == 50000;
123.232K == 123232
1.000000001G == 1000000001
Run Code Online (Sandbox Code Playgroud)
当然,最后一种情况有点违背了目的,因为你再一次有很多零没有视觉指示......所以你可以这样做:
1.G + 1 == 1000000001 // much clearer 1 billion + 1
Run Code Online (Sandbox Code Playgroud)
这使得它有点难看,因为文字需要一个实数,并且不能与整数一起使用,除非您定义一个额外的文字只是为了与整数一起使用。那么你可以简单地使用1G代替。
此外,这种方法可能会产生编译器警告,显然 c++ 组希望保留所有前面没有下划线的后缀以供“将来使用”。如果您希望警告消失,只需使用 _K _M 和 _G 即可。
编辑:我删除了初始化列表解决方案,因为它会产生像 010 这样的数字的无效结果,这些数字被处理为八进制并弄乱了计算。