我正在浏览Google C++ style guide,并发现了这个:
“不要在命名空间std中声明任何内容,甚至不要在标准库类的前向声明中声明。在命名空间std中声明实体是未定义的行为,即不可移植。要从标准库声明实体,请包含相应的头文件。”
有人可以使用示例代码解释这意味着什么以及为什么这是未定义的行为?
答案 0 :(得分:12)
有人可以使用示例代码解释这意味着什么以及为什么这是未定义的行为?
以下程序会产生未定义的行为:
namespace std {
void foo(int) { }
}
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
}
为什么呢?它在名称空间foo
中声明了一个名为std
的函数。至于为什么这会导致问题,请考虑:标准库实现可能有自己的名为foo()
的函数,可能由<iostream>
中的某个组件使用。您的foo
可能比标准库实施的foo
更好。
答案 1 :(得分:12)
首先,像许多Google风格指南一样,它实际上是错误的。该标准特别允许您在命名空间std中定义一些特定实体(例如,现有模板在用户定义类型上的特化)。
然而,忽略这些异常,他们确实有正确的一般想法 - 您的代码通常属于其他而不是命名空间std。您可以将它放在全局命名空间中,也可以定义另一个命名空间,但是应该单独留下std
。
您还应该不尝试在标准库中转发声明任何内容。允许标准函数(例如)包含额外参数,只要它们包含默认值,因此可以以标准方式调用它们。如果你试图自己声明它们,而不是声明现有的函数,你可能最终会声明一个模糊的重载。
底线:是的,使用标准库。当您使用它时,通过包含标准标题来获取声明,而不是通过尝试编写自己的标题。
答案 2 :(得分:6)
这就是说不要在std
命名空间中声明自己的类型。您可以使用标准库,但是您应该通过包含适当的标头来实现。
基本上,请确保所有声明都在您自己的命名空间中,而不是std
。
答案 3 :(得分:5)
他们说你不应该转发从标准库中声明这样的东西:
// myheader.h
namespace std{
template<class T>
void SomeStandardFunction();
}
// use std::SomeStandardFunction
相反,您应该直接包含标题:
// myheader.h
#include <SomeHeaderThatContainsSomeStandardFunction>
// use std::SomeStandardFunction
答案 4 :(得分:2)
这不是说“不要使用标准库”。
使用某些东西并宣布某些东西是两回事。它是说不要声明任何事情,不要做“类ostream”之类的事情。我猜人们过去必须为此声明它才能使用它,但是现在,因为事情是在命名空间std中声明的,所以你只需要包含头文件。
检查this。