在C++中正确使用/包含uint64_t

hun*_*tea 15 c++ c++11

作为参考,我在C++ 11中进行编译.

我开始使用电路板的位图表示作为以片段为中心的方法编写国际象棋引擎.似乎使用的合适类型是uint64_t,但是,在网上搜索了一下之后,我对这里的"最佳实践"有点不确定.

我开始为游戏板定义.hpp文件.首先,我对不同代码似乎表现出来的类似行为感到困惑.

#include <cstdint>
uint64_t board;
Run Code Online (Sandbox Code Playgroud)

和

#include <cstdint>
std::uint64_t board;
Run Code Online (Sandbox Code Playgroud)

编译得很好.两者有什么区别?这个比那个好吗?

另外,我注意到我甚至不需要包含cstdint就可以使用uint64_t:

#include <iostream>
uint64_t board;
Run Code Online (Sandbox Code Playgroud)

和

#include <iostream>
uint64_t std::board;
Run Code Online (Sandbox Code Playgroud)

两者都编译得很好,就像上面的2个cstdint示例一样.因此,我对如何在C++ 11中使用uint64_t感到困惑,以及为什么所有这四个例子都完全相同.我被告知你想使用cstdint,但似乎iostream也提供了类型def?是否存在"最佳/最安全"的特定方式(例如,在名称空间冲突方面)?

Sto*_*ica 25

所述<cthing>标头中的C++存在作为其C-遗产的一部分.标准库不是重新发明轮子,而是重用C标准库的这些有用部分.现在,不同之处在于标题被重命名,并且它们必须在命名空间中定义它们的符号std.他们还可以将它们添加到全局命名空间.请注意,他们可能会这样做,而不是必须.

这是因为这些头(作为实现细节)将包括纯C头<thing.h>并std::根据全局头定义符号.但这不是你可以依赖的东西.标准库实现者可能有一天会决定他们将不再这样做.如果您包含cstdint并使用uint64_t而不是std::uint64_t,您的程序可能会随机停止成功构建.

您唯一的保证是std命名空间中的符号将存在.所以你应该使用这些符号而不是全局符号.

现在,作为其自身实现的一部分,标准库可以在其自身内交叉包含其自己的头.您的版本很可能包含在内<cstdint>以便实施<iostream>.但同样,这是一个实现细节,而不是C++标准的硬性要求.如果您的标准库版本发生更改,而不再更改,则代码将无法构建.

总之,要使代码在不同的编译器和标准库实现中尽可能地可移植:

  1. 包含<cstdint>并使用它在命名空间中定义的符号std,这些符号必须存在.1
  2. 如果您需要任何符号,请在文档中包含保证存在的标题.不要依赖您偶然发现的实施细节.

(1)从技术上讲,允许固定宽度整数类型未定义.这是因为标准意识到并非所有平台都能定义所有平台.实际上,您可以在现代台式机上使用它们.

  • 很好地解释了答案并且非常有帮助,谢谢。 (2认同)
  • @PeterCordes - 这是 POSIX 限制,而不是 C++ 或 C 限制。 (2认同)