1

[namespace.unnamed]/1:

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

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

where inline appears if and only if it appears in the unnamed-namespace-definition and all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit. The optional attribute-specifier-seq in the unnamed-namespace-definition appertains to unique.

I used the example given by @Johannes Schaub - litb in this answer in SO:

namespace A { void f(long); }
using namespace A;

namespace { 
  void f(int);
  void g() {
    ::f(0);
  }
}

If I replace the unnamed-namespace-definition according to [namespace-unnamed]/1, given above, I get the following code:

namespace A { void f(long); }
using namespace A;

namespace unique {}
using namespace unique;
namespace unique {
  void f(int);
  void g() {
    ::f(0);
  }
}

int main(){
    g();
}

which shows that the function g() calls unique::f(int) as can be seen here.

If I replace the unnamed-namespace-definition in the code by

namespace unique { namespace-body }
using namespace unique ;

I get the following code:

namespace A { void f(long); }
using namespace A;

namespace unique {
  void f(int);
  void g() {
    ::f(0);
  }
}
using namespace unique;

int main(){
    g();
}

which shows that the function g() now calls A::f(long) as can be seen here and confirms what @Johannes Schaub said on his answer. I have been trying to find an explanation for these two different behaviors by the compiler in the Standard, to no avail.

Alexander
  • 2,581
  • 11
  • 17
  • `::f(0)` explicitly says "search for `f` in the global namespace". At that point, the only entity named `f` visible in the global namespace is `A::f` (since `using namespace unique;` directive, which would allow finding `unique::f` in the global namespace, hasn't been seen yet). – Igor Tandetnik Oct 24 '20 at 21:10
  • @IgorTandetnik That's fine. But why does it find `f(int)`, but does **not** find `f(long)` in the first code? – Alexander Oct 24 '20 at 21:20
  • It finds both, then overload resolution determines that `f(int)` is a better match for the argument `0` of type `int`. `f(0L)` should call `A::f(long)` – Igor Tandetnik Oct 24 '20 at 21:25
  • Great answer. I never thought this would be so easy. Thanks a lot. – Alexander Oct 24 '20 at 21:28
  • You can go ahead and answer the question yourself. That would allow the post to be resolved. – cigien Oct 31 '20 at 23:43

0 Answers0