定义uint64_t常量的最佳/适当方法

3

constexpr auto v = static_cast<std::uint64_t>(1) << 32;并不是最理想的,因为其语法繁琐且类型转换间接。从这个线程中,我学到了constexpr auto v = UINT64_C(1) << 32; 然而,的精确语义是:

展开为一个整数常量表达式,具有由其参数指定的值和类型uint_least64_t

因此,它并不完全等同于uint64_t。我想知道定义uint64_t常量的最佳/适当方式是什么。

请注意,unsigned long long不一定映射到uint64_t

更新

我不愿使用函数式/C风格转换,因为有些人(例如Google C++编码风格)认为它们来自C,在现代C ++中应避免使用它们。看起来我应该有自己的观点,而不是盲目地跟随别人。


3
好吧,那就用老方法:const uint64_t one = 1ULL; - Jeremy Friesner
5
不使用auto关键字来解决这个问题吗?请说明使用auto相比于简单声明“std::uint64_t v = 1;”带来的好处?无论如何,你可以用U和L修饰你的数字1,使其成为无符号长整型。 - Gem Taylor
@GemTaylor 更新了问题。 - Lingxi
2
为什么不使用函数风格的转换呢?constexpr auto v = std::uint64_t{1} << 32?这与Herb Sutter的“几乎总是auto”建议相辅相成。 - StoryTeller - Unslander Monica
1
@Lingxi:请注意,unsigned long long不一定映射到uint64_t。而且,你的编译器也不一定定义了uint64_t,但是你的代码假设它已经定义了。我看不出这种假设和ULL为64位的假设有什么区别。是否存在提供uint64_t但未定义ULL为64位的真实系统呢? - Nicol Bolas
2个回答

3
因此,它并不完全是uint64_t。我想知道定义uint64_t常量的最佳/适当方式是什么。 如果您想绝对确定,您可以编写uint64_t(1)(可能带有std :: 限定符)作为static_cast的较短替代方法。 实际用途而言,UINT64_C就可以了。如果没有提供满足uint64_t要求的任何类型,则实现不需要定义uint64_t。这是有意义的,因此可以根据uint_least64_t来定义UINT64_C。 但是,在存在uint64_t的实现上(您已经默认使用此类实现),uint64_tuint_least64_t必须具有完全相同的范围,否则实现者几乎肯定会将它们定义为完全相同的类型。 附言:由于此标记为language-lawyer:不能保证uint64_t(1)<< 32仍然具有类型uint64_t。假设,某个实现可能提供比64位更大的int类型,在这种情况下,uint64_t将被提升为int

我在使用函数式转换时有些受限,因为有人说它来自于 C 语言,现代的 C++ 应该避免使用它(比如 Google 的 C++ 编码风格)。实际上,在某些情况下,我发现函数式和 C 风格的转换非常方便和优雅。我想我会对此有自己的看法,而不是盲目地跟随别人的意见。 - Lingxi

-2

有专门的说明符可以实现这一点,使用L将整数字面量变为longLL变为long longULL变为unsigned long long,或者uint64_t(大多数情况下)。

或者干脆不使用auto,让编译器进行隐式转换。


不是事实的是,ULL 并不总是无条件映射到 std::uint64_t - rubenvb
@rubenvb 打算补充一下 - Hatted Rooster
2
尽管在大多数情况下,LL/ULL 可以用于表示 64 位字面量,但是 L/UL 在不同系统上可能会出现问题,因为 Windows 仍然使用 32 位的 long - 0x5453

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接