未命名命名空间内的函数与外部的函数之间存在歧义

发布于 2024-09-17 23:06:43 字数 325 浏览 7 评论 0原文

考虑以下代码片段:

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).
}

在这种情况下,我如何引用匿名名称空间内的某些内容?

Consider the following snippet:

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).
}

How can I refer to something inside an anonymous namespace in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

弥枳 2024-09-24 23:06:43

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

未命名的命名空间定义的行为就像被替换了

  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        
}

You can't. The standard contains the following section (§7.3.1.1, C++03):

An unnamed-namespace-definition behaves as if it were replaced by

  namespace unique { /* empty body */ }
  using namespace unique;
  namespace unique { namespace-body }

where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.

Thus you have no way to refer to that unique name.

You could however technically use something like the following instead:

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        
}
私野 2024-09-24 23:06:43

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

#include <iostream>

using namespace std;

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

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

While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:

#include <iostream>

using namespace std;

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

int main()
{
    cout << inner::cout << endl;
    return 0;
}
末骤雨初歇 2024-09-24 23:06:43

我能想到的唯一不修改现有命名空间安排的解决方案是将 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();
}

The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)

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();
}
梦冥 2024-09-24 23:06:43

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

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

The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.

If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.

后来的我们 2024-09-24 23:06:43

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

Just rename the local namespace function.

居里长安 2024-09-24 23:06:43
void Foo() // 1
{
}

namespace
{
  void Foo() // 2
  {
  }

  namespace detail
  {
    using Func = Foo;
  }
}

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

  using Foo = detail::Func;
  Foo(); // Calls Foo #2.
}
void Foo() // 1
{
}

namespace
{
  void Foo() // 2
  {
  }

  namespace detail
  {
    using Func = Foo;
  }
}

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

  using Foo = detail::Func;
  Foo(); // Calls Foo #2.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文