Pro*_*awn 7 c++ portability c++17
我试图理解 std::variant:
#include <cstdint>
#include <variant>
std::variant<int64_t, double> v;
Run Code Online (Sandbox Code Playgroud)
我想分配一个 int64_t 变体:v = 5L;
它在 x86_64 上编译,因为 int64_t 很长。但它不能在 arm 上编译,因为 int64_t 很长。类型推导现在在 int64_t 和 double 之间有两个相等的选择来转换我的数字,所以它拒绝了。使用 variant<int64_t, string> 我什至不会注意到转换,因为只有一个可用并且编译器会接受它。
类似问题:v = 5LL;现在 arm / 32 位很好,但 x86_64 不再适用。
我在两个平台上都进行了编译,但这(有时)是一种类型转换,具有我无法预见的潜在副作用:v = int64_t(5LL);. 如果没有 LL,我什至无法表达 32 位 int 之外的值。
INT64_C 宏似乎是表达这一点的最便携和最安全的方式:v = INT64_C(5);
但这不再适合读写了。
对于可移植的 int64_t 是否有类似 L/LL 的文字后缀?
不,固定宽度整数别名没有标准文字。
一种潜在的解决方法是使用std::variant<long long, double> v;. 尽管long long理论上不能保证完全是 64 位(它可能更宽,但不会更窄),但实际上在long long当今支持的每个系统上都是 64 位。好处是long long当然有标准的文字。潜在的缺点是理论上尺寸情况将来可能会发生变化。
更通用的解决方案是放弃使用文字后缀,而是使用强制转换:v = static_cast<int64_t>(5);。
另一个解决方案是创建一个用户定义的文字,如评论中链接的答案所示:
Run Code Online (Sandbox Code Playgroud)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