【问题标题】:Use types in <cstdint> with or without namespace在 <cstdint> 中使用带或不带命名空间的类型
【发布时间】:2012-10-29 21:27:39
【问题描述】:

在 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;

【问题讨论】:

  • 我认为 C++11 删除了对 std 中的 C 内容的重构。
  • 我认为您在第一个示例中的意思是“std::”,而不是“std:”
  • @u8sand:没错。谢谢!我更正了。
  • 我会使用#include &lt;stdint.h&gt; uint8_t n = 21;

标签: c++ stl c++11


【解决方案1】:

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

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

如果您使用 &lt;cname&gt; 标头中的名称而不使用 std,则您的程序依赖于未指定的要求。

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

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

除此之外,使用std:: 限定名称有助于避免冲突 - 如果您完全限定它,您将确切地知道您将得到什么。如果你真的要做using namespace stdusing std::something,至少要在尽可能小的范围内进行。

【讨论】:

    【解决方案2】:

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

    • 版本需要将它们添加到全局命名空间中,并且允许将它们添加到std::命名空间。

    • 版本需要将它们添加到std:: 命名空间,并且允许将它们添加到全局命名空间。

    【讨论】:

      【解决方案3】:

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

      如果您决定要在全局命名空间中使用这些名称,您还应该更喜欢&lt;stdint.h&gt; 而不是&lt;cstdint&gt;,然后是using namespace std,因为后者会从其他@987654332 中转储所有其他std 内容@ 标头您也已包含在全局 namspace 中,这可能是您不想要的,因为许多其他标准名称比 uint8_t 之类的名称更容易发生冲突。

      【讨论】:

        【解决方案4】:

        包含&lt;cstdint&gt; 并使用std:: 或包含&lt;stdint.h&gt; 以使用非限定类型名称。在某些平台(例如 QNX SDP 6.6)上,&lt;cstdint&gt; 没有在全局命名空间中声明这些类型。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-19
            • 1970-01-01
            • 2012-05-28
            • 1970-01-01
            • 1970-01-01
            • 2018-08-01
            • 2020-05-31
            • 1970-01-01
            相关资源
            最近更新 更多