在C++中使用标准 C 函数时,是否需要"std::"前缀?
When using standard C functions in C++, is the "std::" prefix required?
在C++中使用标准C函数时,是否应该在每个函数前面加上std::
?
例如(文件名:std.C
):
#include <cstdio>
int main() {
std::printf("hellon");
printf("hellon");
}
这个文件可以用编译
g++ -Wall -Werror -std=c++11 std.C
没有任何错误。
我的问题是:
- 当在C++中使用所有标准C库函数时,我们是否应该始终将
std::
放在它们之前 - 像
<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
。
在我看来,这是不幸的;这似乎是为了方便实现者而不是程序员。最安全的假设是,printf
在std
命名空间中仅声明为。如果您使用#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
。
- std是名称空间,通过使用:(在std之后)显式使用名称空间std的函数。现在,假设您创建了自己的名称空间,并且在那里创建的一些函数与std名称空间中的函数同名。这可能是一个问题,但通过使用std::func1和YourNameSpace::func1可以防止这个问题
- 看这里。谢谢@karma_geek
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 关于std::move的使用,是否有编译警告
- 通过网络、跨平台传递std::变体是否安全
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- std::vector::迭代器是否可以合法地作为指针
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 是否将std::packaged_task添加到现有线程
- C++中是否存在 std::conditional 的懒惰等价物?
- 检查某些类型是否是模板类 std::optional 的实例化
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 为什么程序员同时使用 std::bad_alloc 和 std::exception.是否 std::例外 仅是不够的
- glibcxx STL 在实现 std::valarray::sum() 时是否不正确?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- std::less是否应该允许在编译时比较不相关的指针?