2011-04-16 68 views
6

我一直在寻找通过Google C++ style guide,并遇到了这个:在标准名称空间中声明名称的不良做法?

“不要std下宣布任何事情,标准库类的甚至不向前声明std下声明实体是不确定的行为,即,不便于携带。要从标准库中声明实体,请​​包含相应的头文件。“

有人可以解释这是什么意思,为什么这是未定义的行为使用示例代码?

回答

11

有人可以解释这是什么意思,为什么这是未定义的行为使用示例代码?

下面的程序导致未定义行为:

namespace std { 
    void foo(int) { } 
} 

#include <iostream> 

int main() { 
    std::cout << "Hello World!" << std::endl; 
} 

为什么?它在名称空间std中声明名为foo的函数。至于为什么这可能会导致问题,请考虑:标准库实现可能有其自己的函数,名称为foo(),可能由<iostream>中的某个组件使用。您的foo可能会比标准库实现的foo更好。

+1

除了我们做专门'std :: swap <>()'。我们被允许这样做。 :p – wilhelmtell 2011-04-16 01:30:26

+0

@wilhelmtell:即使那是非常糟糕的形式。最好在与你的类型相同的命名空间中定义一个交换过载,并让ADL完成查找它的工作。 – ildjarn 2011-04-16 01:40:10

+4

@wilhelmtell:你可以_specialize_'std'模板;你不能_overload_'std'模板。对于'swap',正如@ildjarn所说,首选解决方案是使用可以通过ADL找到的命名空间范围函数。 C++ 0x通过添加“可交换”概念给予该技术的正式批准。 – 2011-04-16 01:41:46

6

这是说不要在std命名空间中声明自己的类型。您可以使用使用标准库,但您应该通过包含适当的标头来完成。

基本上,确保你所有的声明都在你自己的命名空间中,而不是std

4

他们说你应该从这样的标准库不向前申报的东西:

// myheader.h 
namespace std{ 
template<class T> 
void SomeStandardFunction(); 
} 

// use std::SomeStandardFunction 

相反,你应该只包括直接头:

// myheader.h 
#include <SomeHeaderThatContainsSomeStandardFunction> 

// use std::SomeStandardFunction 
+0

缺少空格:template > vector; ( - : – snoofkin 2011-04-16 01:41:33

+0

@soul:更加明显的问题是在'allocator'之后缺少';',并且'allocator'在被用作模板参数之前需要被完全定义,所以我改变了这个示例:) – Xeo 2011-04-16 01:49:23

2

这并不是说“不要使用标准库”。

要使用某些东西并声明某些东西是两回事。这是说不要声明任何东西,因为不要像“class ostream;”那样做。我想人们以前必须声明它才能使用它,但现在,因为事物是在名称空间std中声明的,所以只需包含头文件。

检查this出。

10

首先,与Google风格指南中的大部分内容一样,它实际上是错误的。该标准特别允许您在命名空间标准中定义几个特定的​​实体(例如,在用户定义的类型上对现有模板进行专业化)。

但是,忽略这些例外情况,它们确实有正确的总体思路 - 您的代码通常属于其他比命名空间标准。你可以把它放在全局命名空间中,或者你可以定义另一个命名空间,但你应该单独离开std

你也应该不是尝试前向声明标准库中的任何东西。标准函数允许(例如)包含额外的参数,只要它们包含默认值,这样就可以用标准方式调用它们。如果你尝试自己声明它们,而不是声明现有的函数,那么最终可能会声明一个模糊的超载。

底线:是的,请使用标准库。当你使用它时,通过包含标准头文件来获取声明,而不是通过编写自己的头文件。

+1

+1击败我:“它实际上是错误的......现有模板的专业化......”。专门研究'std :: swap <>()'是一种常见和可接受的做法。 “ – wilhelmtell 2011-04-16 01:28:52

+4

+1”首先,**像很多Google风格指南**一样,实际上是错误的。“ – ildjarn 2011-04-16 02:29:42

相关问题