【问题标题】:Is there a portable literal suffix for int64_t and similar types?int64_t 和类似类型是否有可移植的文字后缀?
【发布时间】:2020-12-22 10:14:13
【问题描述】:

我试图理解 std::variant:

#include <cstdint>
#include <variant>

std::variant<int64_t, double> v;

我想分配一个 int64_t 变体:v = 5L; 这在 x86_64 上编译,因为 int64_t 很长。但它不能在 arm 上编译,因为 int64_t 很长。类型推导现在在 int64_t 和 double 之间有两个相等的选择来转换我的数字,所以它拒绝了。使用 variant 我什至不会注意到转换,因为那时只有一个可用并且编译器会接受它。

类似问题:v = 5LL; 现在 arm / 32 位很好,但 x86_64 不再可用。

我在两个平台上都进行了编译,但这(有时)是一种类型转换,具有我无法预见的潜在副作用:v = int64_t(5LL);。如果没有 LL,我什至无法表达 32 位整数之外的值。

INT64_C 宏似乎是表达这一点的最便携和最安全的方式:v = INT64_C(5); 但这已经不适合阅读和写作了。

对于 int64_t 是否有类似 L/LL 的字面后缀可移植?

【问题讨论】:

  • 一个简单的解决方案是使用强制转换:int64_t i = (int64_t)5;。 (而且它是完全可移植的,并在编译时解析。)
  • 这能回答你的问题吗? UL suffix vs uint32_t cast
  • 另一种选择可能是自己定义一个文字运算符:SO: Fixed-width integer literals in C++?(我可以发誓我在某处读到它们可能会被添加到标准中......)
  • @scheff:我什至没想到 c-cast 会起作用,但它似乎起作用了。最后,我不想在 c++ 中使用 c-casts,而是可能会写 static_cast(...) 。但是构造函数符号 int64_t(...);对眼睛更好,至少对我来说。整数文字方法似乎是前进的最佳方式,感谢您的提示。
  • 我更喜欢 C-casts,因为我太老了,无法使用正确的 C++ casts。在大多数情况下(dynamic_cast 被排除在外,即使我已经习惯了)它会达到预期的效果...... ;-)

标签: c++ c++17 portability


【解决方案1】:

不,没有固定宽度整数别名的标准文字。

一种可能的解决方法是使用std::variant&lt;long long, double&gt; v;。尽管long long 理论上不能保证正好是 64 位(它可能更宽,但不会更窄),但在今天几乎所有支持long long 的系统上它都是 64 位。好处是 long long 当然有一个标准的文字。潜在的缺点是规模情况在理论上可能会在未来发生变化。

更通用的解决方案是放弃使用文字后缀,而是使用强制转换:v = static_cast&lt;int64_t&gt;(5);。

另一种解决方案是创建一个用户定义的文字,如 cmets 中链接的 answer 所示:

constexpr std::int64_t operator "" _int64(unsigned long long v)
{ return static_cast<std::int64_t>(v); }

有一个建议将这样的文字添加到标准库中:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1280r2


在相关说明中,有人提议为std::size_t 和std::ptrdiff_t 添加文字。该提案建议使用核心语言文字而不是标准库文字:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0330r3

【讨论】:

    猜你喜欢
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2016-06-10
    • 2012-06-25
    • 2016-10-04
    • 2013-08-09
    相关资源
    最近更新 更多