7

我正在学习 C++11,并且对用户定义的文字感兴趣。所以我决定玩一下它。有些语言有这样的语法:

int n = 1000_000_000;

我试图在 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;
}

但是对于一般情况我无法模拟它,即

自动general_case = 123_456_789;//无法编译

我的问题是“我可以使用 C++11 模拟上述一般情况吗?”。

4

1 回答 1

4

这对于现在的 C++11 版本的语言中的用户定义文字是不可能的。用户定义的文字支持有限的参数格式,似乎不支持右侧参数,链接,另外还有以 0 开头的数字表示为实际数字的问题。所以这是不行的。

您当前的方法将 _000 等定义为独立的文字,因此编译器只能使用它们而不能使用其他。不幸的是,它不像_is 运算符,000而是您可以使用的一些参数。

但是,您可以改用字母后缀。

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;
}

接着:

0.05M == 50000;
123.232K == 123232
1.000000001G == 1000000001

当然,最后一种情况违背了目的,因为你再次有许多没有视觉指示的零......所以你可以选择类似的东西:

1.G + 1 == 1000000001 // much clearer 1 billion + 1

这使它有点难看,因为文字需要一个实数并且不能与整数一起使用,除非您定义一个额外的文字只是为了与整数一起使用。然后你可以简单地使用 1G 来代替。

此外,这种方法可能会产生编译器警告,显然 c++ 小组希望保留所有前面没有下划线的后缀以供“将来使用”。如果您希望警告消失,只需使用 _K _M 和 _G 代替。

编辑:我删除了初始化列表解决方案,因为它会产生无效的结果,如 010 之类的数字,它被处理为八进制并弄乱了计算。

于 2013-08-20T07:20:53.170 回答