15

在 C++11 中,我可以选择是否要使用定义的类型,带或不带命名空间 std::

至少我的编译器(g++ 4.7)接受这两种变体。

我的问题是:使用 cstdint 中的 typedef 的推荐方法是什么。有或没有命名空间?有什么优点或缺点?还是只是风格问题?

所以变体a):

#include <cstdint>
std::uint8_t n = 21;

回复:

#include <cstdint>
using std::uint8_t;
uint8_t n = 21;

或变体 b):

#include <cstdint>
uint8_t n = 21;
4

5 回答 5

12

首选在std命名空间中声明的名称。原因在 §17.6.1.3/4 ( ISO/IEC 14882:2011(E) , C++11) 中给出:

除了第 18 到 30 条和附录 D 中的说明外,每个头文件cname的内容应与相应的头文件名称.h的内容相同,如 C 标准库 (1.2) 或 C Unicode TR 中规定的,视情况而定,如如果通过包含。但是,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在 namespace 的命名空间范围 (3.3.6) 内stdstd未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式使用声明(7.3.3)注入命名空间。

如果您使用不带 的<c名称>标题中的名称std,则您的程序依赖于未指定的要求。

这在 C++03 和更早版本中有所不同,其中名称只应该出现在std命名空间中。然而,现实情况是,许多实现只是将 C 标准库头文件<名称.h>的内容注入到std其中,因此在 C++11 中已经适应了这一点。C++03 标准的相应部分(§17.4.1.2/4)说:

除第 18 至 27 条中的说明外,每个头cname的内容应与相应头名称.h的内容相同,如 ISO/IEC 9899:1990 编程语言 C(第 7 条)或 ISO/IEC:1990 中规定的编程语言——C 修正案 1:C 完整性,(第 7 条),视情况而定,如同包含。但是,在 C++ 标准库中,声明和定义(在 C 中定义为宏的名称除外)在 namespace 的命名空间范围 (3.3.5) 内std

除此之外,限定名称std::有助于避免冲突——如果你完全限定它,你就会确切地知道你得到了什么。如果你真的打算做using namespace stdor using std::something,至少在尽可能小的范围内做。

于 2012-10-29T21:35:07.100 回答
7

在 C++11 中,对于在 C++ 标准中明确命名的 C 头文件,以下内容成立:

  • <foo.h> 版本需要实现才能将它们添加到全局命名空间中,并允许将它们添加到std::命名空间中。

  • <cfoo> 版本需要实现才能将它们添加到std::命名空间中,并允许将它们添加到全局命名空间中。

于 2012-10-29T21:34:46.827 回答
4

std将命名空间中的内容包装在<cstdint>标头中的原因是为了避免名称冲突,当它们发生时会非常不愉快。但是,在这种情况下,这些类型不太可能在其他地方找到。所以我会使用<stdint.h>,特别是因为这个特性是在C它被添加到之前引入的C++,因此<stdint.h>头文件比 旧<cstdint>,因此在旧的编译器中可用。

如果您决定要在全局命名空间中使用这些名称,您还应该更喜欢后跟,因为后者会将您已包含的其他标头中的所有其他内容也转储<stdint.h>到全局命名空间中,您可能不想要,因为许多其他标准名称比 uint8_t 之类的名称更容易发生冲突。<cstdint>using namespace stdstd<cfoo>

于 2012-10-29T21:42:39.440 回答
2

包含<cstdint>并使用std::或包含<stdint.h>使用非限定类型名称。有一些平台(例如 QNX SDP 6.6)<cstdint>没有在全局命名空间中声明这些类型。

于 2018-12-08T00:11:21.153 回答
1

我的个人风格是始终完全限定名称,以便清楚它们的来源。也就是说,我会使用std::uint8_t. 也就是说,我将包含<cstdint>并使用限定名称。

也就是说,请注意,std::uint8_t仅当您真的打算使用正好是8 位的类型时才指示使用。如果您运行代码的平台没有这样的类型,例如,因为它使用 9 位单元作为其基本实体,则程序不应该编译。如果你想使用最小unsigned的 8 位可用,你想使用uint_least8_t.

于 2012-10-29T21:35:04.093 回答