在C ++中使用标准C函数时,我们应该为每个函数添加std::
吗?
(文件名:std.C
):
#include <cstdio>
int main() {
std::printf("hello\n");
printf("hello\n");
}
可以使用以下命令编译此文件:
g++ -Wall -Werror -std=c++11 std.C
没有任何错误。
我的问题是:
std::
置于所有标准C库函数之前?<stdio.h>
和<cstdio>
等标题文件之间的主要区别是什么?答案 0 :(得分:9)
C ++库包含与C语言相同的定义 库中组织了与头文件相同的结构,用 以下差异:
- 每个头文件与C语言版本具有相同的名称,但前缀为“
c
”且没有扩展名。例如,C ++等价物 对于C语言头文件<stdlib.h>
是<cstdlib>
。- 库的每个元素都在
std
命名空间中定义。然而,为了与C兼容,传统的标题名称
name.h
(如stdlib.h
)也提供了相同的定义 尽管在C ++中不推荐使用它,但在全局命名空间中。
(source)
std::
调用的std::printf()
部分是在标准库中使用名称的标准方法,因此,我建议使用它。
答案 1 :(得分:3)
C ++标准库包含C标准库(稍作调整)。
每个名为<foo.h>
的C标头都有一个对应的C ++标头<cfoo>
。例如,C ++标头<cstdio>
对应于C标头<stdio.h>
。
引用2011 ISO C ++标准,17.6.1.2 [header]第4段:
然而,在C ++标准库中,声明(除了 在C)中定义为宏的名称在命名空间范围内 名称空间
std
的(3.3.6)。这些名称是否未指明 首先在全局命名空间范围内声明,然后是 通过显式 using-declarations (7.3.3)注入名称空间std
。
因此,#include <cstdio>
printf
函数肯定可以称为std::printf
,而可选可以显示为全局命名空间中的printf
。 (此选项取决于实现,而不是程序员。)
当然,您可以在printf
的范围内将其称为using namespace std
。
在我看来,这是不幸的;它似乎是为了方便实施者而不是程序员。最安全的做法是假设在printf
命名空间中std
仅声明 。如果您使用#include <cstdio>
然后在全局命名空间中引用printf
,那么您的代码今天可能会编译而无法在不同的实现上进行编译。
相反,作为已弃用的功能,C ++标准库还包含带有原始名称的C标准标头,例如<stdio.h>
。引用标准,第D.5节[depr.c.header]:
每个C标头,每个标头都有
name.h
形式的名称, 表现就像每个名称放在标准库名称空间中一样 相应的 cname 标头位于全局命名空间内 范围。未指定是否首先声明这些名称或 在命名空间std
的命名空间范围(3.3.6)中定义 然后通过显式注入全局命名空间范围 using-declarations (7.3.3)。
所以给定#include <stdio.h>
,名称printf
肯定在全局命名空间中可见,而可选(同样,这是实现的选项) ,而不是你的)std::printf
可见。
答案 2 :(得分:1)