匿名命名空间歧义

时间:2010-09-09 02:21:22

标签: c++ namespaces anonymous ambiguity

请考虑以下代码段:

void Foo() // 1
{
}

namespace
{
  void Foo() // 2
  {
  }
}

int main()
{
  Foo(); // Ambiguous.
  ::Foo(); // Calls the Foo in the global namespace (Foo #1).

  // I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}

在这种情况下,如何引用匿名命名空间内的内容?

5 个答案:

答案 0 :(得分:18)

你做不到。该标准包含以下部分(§7.3.1.1,C ++ 03):

  

unnamed-namespace-definition的行为就像它被

替换一样
  namespace unique { /* empty body */ }
  using namespace unique;
  namespace unique { namespace-body }
  

所有出现的独特之处   翻译单位被替换   相同的标识符和此标识符   与整个计划中的所有其他标识符不同。

因此,您无法引用该唯一名称。

然而,您可以在技术上使用以下内容:

int i;

namespace helper {
    namespace {
        int i;
        int j;
    }
}

using namespace helper;

void f() { 
    j++; // works
    i++; // still ambigous
    ::i++; // access to global namespace
    helper::i++; // access to unnamed namespace        
}

答案 1 :(得分:5)

虽然Georg给出了标准的,正确的,正确的,可敬的答案,但我想提供我的hacky - 在匿名命名空间中使用另一个命名空间

#include <iostream>

using namespace std;

namespace
{
namespace inner
{
    int cout = 42;
}
}

int main()
{
    cout << inner::cout << endl;
    return 0;
}

答案 2 :(得分:2)

我能想到的唯一解决方案是不修改现有的命名空间安排,即将main委托给匿名命名空间中的函数。 (main本身必须是一个全局函数(§3.6.1/ 1),因此它不能在匿名命名空间中。)

void Foo() // 1
{
}

namespace
{
  void Foo() // 2
  {
  }
}

namespace { // re-open same anonymous namespace

    int do_main()
    {
      Foo(); // Calls local, anonymous namespace (Foo #2).
      ::Foo(); // Calls the Foo in the global namespace (Foo #1).

      return 0; // return not optional
    }

}

int main() {
    return do_main();
}

答案 3 :(得分:0)

唯一真正的方法是将您想要访问该命名空间的代码放在命名空间本身中。否则,无法解析为未命名的命名空间,因为它没有标识符,您可以使用它来解决模糊解决问题。

如果您的代码位于namespace {}块本身内,则本地名称优先于全局名称,因此Foo()将在您的命名空间中调用Foo(),而:: Foo()将调用全局范围内的命名空间。

答案 4 :(得分:0)

只需重命名本地命名空间函数。