【问题标题】:When using standard C functions in C++, is the "std::" prefix required? [duplicate]在 C++ 中使用标准 C 函数时,是否需要“std::”前缀? [复制]
【发布时间】:2015-07-06 00:27:59
【问题描述】:

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

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

#include <cstdio>

int main() {
  std::printf("hello\n");
  printf("hello\n");
}

这个文件可以编译:

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

没有任何错误。

我的问题是:

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

【问题讨论】:

  • 1 是 2 一个已弃用,另一个未弃用。
  • @KerrekSB 而且,一个是C,另一个是C++。 C++ 不是 C 的超集。
  • (1) 是的,但这取决于。 (2) &lt;cstdio&gt; 将函数包装在 std 命名空间中。第一个是为了向后兼容而存在的。
  • @KerrekSB:3. 停止在 cmets 中回答。

标签: c++ c


【解决方案1】:

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

  • 每个头文件都与 C 语言版本同名,但带有“c”前缀且没有扩展名。例如,C++ 等价物 对于C语言头文件&lt;stdlib.h&gt;&lt;cstdlib&gt;
  • 库的每个元素都在 std 命名空间中定义。

不过,为了与 C 兼容,传统的标头名称 name.h(如stdlib.h)也提供了相同的定义 在全局命名空间中,尽管它在 C++ 中已被弃用。

(source)

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

【讨论】:

  • 另请注意,C++ 标准允许 C++ 对应的 C std lib 标头将名称放在全局命名空间中。
  • 允许。不需要。
  • &lt;cstdio&gt; 中声明的标识符包含在全局命名空间中,以及将&lt;stdio.h&gt; 中声明的标识符包含在std 中是可选。看我的回答。
【解决方案2】:

C++ 标准库合并了 C 标准库(有一些小的调整)。

每个名称如 &lt;foo.h&gt; 的 C 标头都有一个对应的 C++ 标头 &lt;cfoo&gt;。比如C++头&lt;cstdio&gt;对应C头&lt;stdio.h&gt;

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

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

所以给定#include &lt;cstdio&gt;printf 函数肯定可以被称为std::printf,并且可选地可以在全局中显示为printf命名空间。 (这个选项取决于实现,而不是程序员。)

当然你可以在using namespace std的范围内将它称为printf

在我看来,这很不幸;这似乎是为了方便实现者而不是程序员。假设printfstd 命名空间中only 被声明是最安全的。如果您使用#include &lt;cstdio&gt;,然后在全局命名空间中引用printf,您的代码今天可能会编译,而无法在不同的实现上编译。

相反,作为一个已弃用的特性,C++ 标准库还包含带有原始名称的 C 标准头文件,例如 &lt;stdio.h&gt;。引用标准,第 D.5 节 [depr.c.header]:

每个 C 标头,每个标头都有一个 name.h 形式的名称, 表现得好像每个名称都放置在标准库命名空间中 相应的 cname 标头放置在全局命名空间中 范围。未指定这些名称是首先声明还是 在命名空间 std 的命名空间范围 (3.3.6) 内定义和 然后通过显式注入到全局命名空间范围内 使用声明 (7.3.3)。

所以给定#include &lt;stdio.h&gt;,名称printf绝对在全局命名空间中可见,并且可选(同样,这是实现的选项,不是你的)可见为std::printf

【讨论】:

  • &lt;printf.h&gt;?你的最后一句话是指“给定#include &lt;stdio.h&gt;”吗?
  • @zmb:确实如此,谢谢(已修复)。
【解决方案3】:
  1. std 是命名空间,通过使用 ::(在 std 之后),您可以显式使用命名空间 std 的功能。现在,假设您创建了自己的命名空间,并且您在那里创建的一些函数与 std 命名空间中的函数具有相同的名称。这可能是个问题,但是通过使用 std::func1 和 YourNameSpace::func1 可以避免这个问题。
  2. Look in here。谢谢@karma_geek

【讨论】:

  • “看这里”没有回答这个问题。请把内容带到这里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多