Anonymous Namespace Ambiguity

前端 未结 5 2029
我在风中等你
我在风中等你 2020-12-18 19:51

Consider the following snippet:

void Foo() // 1
{
}

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

int main()
{
  Foo(); // Ambiguous.
  ::Foo(); // Calls the Foo         


        
相关标签:
5条回答
  • 2020-12-18 20:01

    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();
    }
    
    0 讨论(0)
  • 2020-12-18 20:16

    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        
    }
    
    0 讨论(0)
  • 2020-12-18 20:16

    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;
    }
    
    0 讨论(0)
  • 2020-12-18 20:20

    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.

    0 讨论(0)
  • 2020-12-18 20:22

    Just rename the local namespace function.

    0 讨论(0)
提交回复
热议问题