【问题标题】:Global namespace is not checked in other namespaces全局命名空间未在其他命名空间中检查
【发布时间】:2013-11-07 04:08:39
【问题描述】:

我试图在我的代码中使用命名空间,所以我有一个如下所示的头文件:

#include <string>

namespace AppNamespace
{
  class A
  {
    std::string name;
  };
}

当我尝试编译它时,它说“'string' 不是 AppNamespace::std 的成员”。如果我删除字符串前面的std::,或者如果我写::std::string name,那么它会编译得很好。

这当然是一个简化的例子,我有很多头文件,并不是所有的头文件都显示这种行为。我不确定是什么原因造成的,我认为编译器也会尝试全局命名空间。

如果这很重要,我目前正在使用 Visual Studio 2012。

【问题讨论】:

  • 由于某种原因,AppNamespace 是否包含名为 std 的内容?
  • 你能生成一个sscce.org 吗?还有一些你没有描述的事情。

标签: c++ namespaces


【解决方案1】:

这当然是一个简化的例子,我有很多头文件,并不是所有的头文件都显示这种行为。我不确定是什么原因造成的,我认为编译器也会尝试全局命名空间。

在某些时候你必须有这样的东西:

namespace AppNamespace
{
  #include <string> // or #include "my_header" which in turn includes <string>

  class A
  {
    std::string name;
  };
}

#include 指令不尊重命名空间。您需要将它们全部移到全局命名空间范围内,否则每个(可能嵌套的)标准标头包含将导致以创建嵌套命名空间std 的形式出现未定义的行为。

【讨论】:

  • 我认为这最终是这样的。我在某个地方有一个命名空间,但没有用花括号正确关闭。
【解决方案2】:

使用:

using namespace std;

#include <iostream>
#include "test_header.h"

int main() ...

代码以上述示例作为标头进行编译。

移动

使用命名空间标准;

如果我不使用std::string,头文件(在我的例子中是test_header.h)下面会导致它失败。

这是你遇到的问题吗?

【讨论】:

  • 我也在使用 VS2012 顺便说一句。
  • 如果我删除 using namespace std;我的头文件(如您所述)编译。
  • 你不应该使用using namespace std;,因为它可能会导致范围问题和命名冲突,只需使用 std:: 前缀
  • 我认为在实现文件中使用它是可以的,但永远不要在头文件中使用它,因为它会污染包含它的所有其他文件
  • @David using namespace std; 在标头中是访问std 命名空间的最糟糕的方式。您还有其他选择:您可以选择性地使用类型,例如using std::wstring;,并且您可以将 using 语句放在类成员实现中。 void X::foo() { using std::wstring; wstring str( L"bar" ); ... }
猜你喜欢
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 2013-11-22
  • 2012-03-12
相关资源
最近更新 更多