【问题标题】:C++11 user-defined literals [duplicate]C ++ 11用户定义文字[重复]
【发布时间】:2013-08-20 06:10:04
【问题描述】:

我正在学习 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 模拟上述一般情况吗?”。

【问题讨论】:

  • 对 1_000_000 有效吗?我个人会使用自定义用户文字和字母 K M G(千兆千兆)。
  • 1_000_000 编译!!!
  • @ddriver 唯一的问题是你不能那么准确
  • 为什么不呢,你可以选择 1_234 或者 1.234K 来舍入到相同的整数? @KhurshidNormuradov - 你只为 _000 定义了它,如果你想要更多的“精确度”,你需要将 _ 作为一个独立的后缀,它需要在右边使用另一个参数,但我不知道这是否是可能。
  • 这个确切的功能几乎使它进入了 C++14。预计它将在 2015 年左右进入编译器,并在 2017 年左右正式标准化。open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3661.html

标签: c++ c++11 user-defined-literals


【解决方案1】:

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

您当前的方法将 _000 等定义为独立的文字,因此编译器只能使用它们而不能使用其他。不幸的是,_ 不是运算符,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,它被处理为八进制并弄乱了计算。

【讨论】:

  • 是的,如果问题有很多尾随零,你就解决了这个问题,但你没有解决一般情况(例如123456789 -> 123456.789K -> 123.456789M -> 没有明显的好处)
  • @LightnessRacesinOrbit - 我同意这几乎毫无意义,但它仍然可以作为 OP 的一个例子,因为他们显然弄错了文字。我实际上对 RHS 参数和链接有期望,目前形式的文字似乎相当初级。
猜你喜欢
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
相关资源
最近更新 更多