int64_t 和类似类型是否有可移植的文字后缀?

Is there a portable literal suffix for int64_t and similar types?

我试图理解 std::variant:

#include <cstdint>
#include <variant>

std::variant<int64_t, double> v;

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

类似问题:v = 5LL; 现在 arm / 32 位没问题,但 x86_64 不行了。

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

INT64_C 宏似乎是最便携、最安全的表达方式:v = INT64_C(5); 但是这样读和写都不好看了。

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

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

一种可能的解决方法是使用 std::variant<long long, double> v;。尽管 long long 理论上不能保证正好是 64 位(它可能更宽,但不会更窄),但实际上现在每个支持 long long 的系统都是 64 位。好处是 long long 当然有标准字面量。潜在的缺点是尺寸情况在理论上可能会在未来发生变化。

一个更通用的解决方案是放弃使用文字后缀,而是使用强制转换:v = static_cast<int64_t>(5);.

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

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_tstd::ptrdiff_t 添加文字。该提案建议使用核心语言文字而不是标准库文字:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0330r3