在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;
答案 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>
并未在全局名称空间中声明这些类型。