【问题标题】:cstdio stdio.h namespacecstdio stdio.h 命名空间
【发布时间】:2012-05-05 08:45:30
【问题描述】:

我从 cstdio 的 c++ 参考中看到这一行:

库的每个元素都在 std namespace 中定义。 但我尝试了代码:

std::printf("hello world"); 

printf("hello world");

C++ 标头是否将名称同时放在 std 和全局命名空间中

【问题讨论】:

    标签: c++ header


    【解决方案1】:

    包括cstdio 会在std 命名空间中导入符号名称,可能在全局命名空间中。
    包括stdio.h 会在全局命名空间中导入符号名称,可能std 命名空间中。

    这同样适用于所有 c 样式的标题。


    参考:
    C++11 标准

    附录 D(规范性)兼容性特性 [depr] 规定:

    D.6 C 标准库头文件

    1 为了与 C 标准库和 C Unicode TR 兼容,C++ 标准库提供了 25 个 C 标头,如表 151 所示。

    其中包括:

    <assert.h> <float.h> <math.h> <stddef.h> <tgmath.h> <complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h> <ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h> <errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h> <fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

    进一步,

    2 每个 C 标头都有一个 name.h 形式的名称,其行为就像每个由相应 cname header 放置在标准库命名空间中的名称都放置在全局命名空间范围内一样。 未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式 using 声明 (7.3.3) 注入全局命名空间范围。

    3 [ 示例:标题<cstdlib> 确实在命名空间std 中提供了它的声明和定义。它还可以在全局命名空间中提供这些名称。标题<stdlib.h> 确实在全局命名空间中提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间 std 中提供这些名称。 ——结束示例]

    【讨论】:

    • 所以这取决于实现?有趣,我不知道。
    • @MrLister:是的,标准明确说明这一点并没有混淆。
    • 我是否更愿意包含 并且“stdio.h”已“弃用”?
    • @javapowered 官方来说,是的。自 C++11 起,C 兼容性标头已在标准的“兼容性特性”附件中指定,该附件描述了 “不推荐使用的特性,其中 deprecated 定义为:本国际标准当前版本的规范性,但已被确定为从未来修订中删除的候选者”。不过,将它们标记为“被确定为移除的候选者”可以说是不正当的。 open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0619r0.html#3.5 认为标头将永远保留,并且不应该被弃用。
    【解决方案2】:

    根据 libstdc++ 文档:

    标准规定,如果一个包含 C 样式的标题 (在这种情况下为<math.h>),这些符号将在 global 命名空间,也许在命名空间 std:: 中(但这不再是一个公司 要求。)另一方面,包括 C++ 样式的标头 (<cmath>) 保证实体将在 namespace std 中找到 并且可能在全局命名空间中。

    http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch03s02.html

    【讨论】:

    • 我认为如果我们使用<cmath>,那么它将保证实体在namespace std下可用,因此不在全局命名空间中。
    猜你喜欢
    • 2010-11-04
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多