在C++中使用标准 C 函数时,是否需要"std::"前缀?

When using standard C functions in C++, is the "std::" prefix required?

本文关键字:是否 std 前缀 C++ 标准 函数      更新时间:2023-10-16

在C++中使用标准C函数时,是否应该在每个函数前面加上std::

例如(文件名:std.C):

#include <cstdio>
int main() {
std::printf("hellon");
printf("hellon");
}

这个文件可以用编译

g++ -Wall -Werror -std=c++11 std.C

没有任何错误。

我的问题是:

  1. 当在C++中使用所有标准C库函数时,我们是否应该始终将std::放在它们之前
  2. <stdio.h><cstdio>这样的头文件的主要区别是什么

C++库包含与C语言相同的定义库以相同的头文件结构组织,具有以下差异:

  • 每个头文件的名称与C语言版本相同,但前缀为"c",没有扩展名。例如,C++等价物对于C语言头文件CCD_ 7是CCD_
  • 库的每个元素都是在std命名空间中定义的

然而,为了与C兼容,传统的标头名称name.h(类似于stdlib.h)也具有相同的定义在全局命名空间中,尽管在C++中不赞成使用它。

(来源)

std::printf()调用的std::部分是在标准库中使用名称的标准方式,因此,我建议使用它

C++标准库包含了C标准库(有一些小调整)。

具有类似<foo.h>的名称的每个C报头具有相应的C++报头<cfoo>。例如,C++报头<cstdio>对应于C报头<stdio.h>

引用2011年ISO C++标准,17.6.1.2[标题]第4段:

然而,在C++标准库中在C)中定义为宏的名称在命名空间范围内命名空间std的(3.3.6)。未指定这些名称首先在全局命名空间范围内声明,然后通过显式使用声明注入命名空间std(7.3.3)。

因此,给定#include <cstdio>printf函数肯定可以称为std::printf,并且可选在全局命名空间中可以作为printf可见。(这个选项取决于实现,而不是程序员。)

当然,您可以将其称为using namespace std范围内的printf

在我看来,这是不幸的;这似乎是为了方便实现者而不是程序员。最安全的假设是,printfstd命名空间中仅声明为。如果您使用#include <cstdio>,然后在全局命名空间中引用printf,那么您的代码可能会在今天编译,并且无法在其他实现上编译。

相反,作为不推荐使用的功能,C++标准库还包括具有原始名称的C标准头,如<stdio.h>。引用标准,第D.5节[depr.c.header]:

每个C头,每个头都有一个形式为name.h的名称,行为方式就像将每个名称放置在标准库命名空间中一样相应的cname标头被放置在全局命名空间中范围未指定这些名称是首先声明的还是在命名空间std的命名空间范围(3.3.6)内定义,以及然后通过显式使用声明(7.3.3)。

因此,给定#include <stdio.h>,名称printf在全局命名空间中肯定是可见的,并且可选地(同样,这是实现的选项,而不是您的选项)可见为std::printf

  1. std是名称空间,通过使用(在std之后)显式使用名称空间std的函数。现在,假设您创建了自己的名称空间,并且在那里创建的一些函数与std名称空间中的函数同名。这可能是一个问题,但通过使用std::func1和YourNameSpace::func1可以防止这个问题
  2. 看这里。谢谢@karma_geek
相关文章: