在<cstdint>中使用带或不带命名空间</cstdint>的类型

时间:2012-10-29 21:27:39

标签: c++ stl c++11

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

的类型

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

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

所以变种a):

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

RESP:

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

或变体b):

#include <cstdint>
uint8_t n = 21;

5 个答案:

答案 0 :(得分:6)

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

  

除第18条至第30条及附件D中所述外,每个标题 cname 的内容应与相应标题名称 {{1}的内容相同。 },如C标准库(1.2)或C Unicode TR中所指定的,视情况而定,如同包含一样。但是,在C ++标准库中,声明(除了在C中定义为宏的名称除外)在命名空间.h的命名空间范围(3.3.6)内。未指定是否首先在全局命名空间范围内声明这些名称,然后通过显式 using-declarations (7.3.3)将这些名称注入命名空间std

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

这在C ++ 03及更早版本中有所不同,其中名称只应出现在std命名空间中。但是,实际情况是,许多实现只是将C标准库标题std name <的内容注入.h>,因此适用于C ++ 11。 C ++ 03标准的相应部分(第17.4.1.2 / 4节)说:

  

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

除此之外,使用std的合格名称有助于避免碰撞 - 如果您完全符合条件,您就知道自己获得了什么。如果你真的要做std::using namespace std,至少要尽可能在最小的范围内进行。

答案 1 :(得分:4)

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

  • &lt; foo.h&gt;的实施必需将它们添加到全局命名空间中的版本,以及允许将它们添加到std::命名空间。

  • &lt; cfoo&gt;的实施必需将它们添加到std::命名空间中的版本,以及允许将它们添加到全局命名空间。

答案 2 :(得分:2)

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

如果您已确定要在全局命名空间中使用这些名称,则还应该更喜欢<stdint.h><cstdint>,后跟using namespace std,因为后者会转储所有其他std <cfoo>来自其他{{1}}标题的东西也包含在全局namspace中,你可能不想要它,因为许多其他标准名称比uint8_t更容易发生碰撞。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

包含<cstdint>并使用std::或包含<stdint.h>以使用不合格的类型名称。在某些平台(例如QNX SDP 6.6)上,<cstdint>并未在全局名称空间中声明这些类型。