为什么我们不能在C ++中的名称空间中包含std头

时间:2011-01-05 07:22:33

标签: c++

以下代码将导致g ++ 4.4中的编译错误:

// File test.cpp
namespace A
{
    #include <iostream>
}

int main()
{
    return 0;
}

我有这个要求,因为某些第三方库没有受名称空间保护,如果我直接包含这些标题,我的名称空间就会受到污染。
因此,我尝试为这些库创建名称空间,但如果库包含一些“标题标题”,则上述方法将失败。

有人可以帮忙吗?

谢谢!

3 个答案:

答案 0 :(得分:6)

我相信17.4.2.1 [lib.using.headers]禁止在命名空间中包含标准库头:

  

翻译单位应仅在任何外部声明或定义之外包含标题,并且必须   在首次引用它之前声明或首先定义的任何实体之前,在词汇上包含头   翻译单位。

除了向图书馆作者提交请求之外,我认为你无能为力。

答案 1 :(得分:1)

这种方法很可能会让您遇到麻烦。您可以通过在进入命名空间之前手动包含每个此类标准标头来解决问题,并且包含警卫会负责不在命名空间内重新包含标头。

这会照顾你当前的错误,但另一方面会破坏太多其他东西 - 如果库是预编译的,那么代码中使用的符号和二进制库中的符号将是不同的符号(您的代码中使用了libname::foo(),二进制文件中定义了::foo()。即使库只是标题,对库中库的任何完全限定访问都会中断(void foo() { ::bar(); }其中foobar在库中。)

您可能想要尝试的有效方法(即使繁琐且需要实际工作)将编写一个包含在其自己的命名空间内的包装器,并使用该库。然后包括您的包装器而不是实际的库头。

另一方面,我的建议完全忽略了这个问题。在命名空间中声明自己的对象,这将处理可能的名称冲突。只要你远离using namespace陈述,你就可以了。

答案 2 :(得分:0)

在使用std::cout等标准库调用时,请使用完全限定名称,而不是编写using namespace std;。这样,两者都可以共存。