Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ ADL in nested namespaces with template function

I have a question regarding the standard ADL resolution in C++.

Here is a sample code explaining my enquiry:

#include <string>

// The mechanism:
namespace A {

 template< class C >
 ::std::string scope(const C*)
 { return "A"; }

 namespace B {

  template< class C >
  ::std::string scope(const C *foo)
  { return A::scope(foo)+"::B"; }

 } // namespace B
} // namespace A

::std::string scope(...)
{ return ""; }

// The test classes
struct foo {};
namespace A {
 struct foo {};
 namespace B {
  struct foo {};
 }
}

// The usage
int main()
{
  foo *Foo=0;
  A::foo *FooA=0;
  A::B::foo *FooB=0;

  scope(Foo);  // OK, returns ""
  scope(FooA); // OK, returns "A"
  scope(FooB); // On one compiler, OK returns "A::B" ; On another, compiler error "Ambiguous call" between A::scope() and A::B::scope()
}

So, my question is what is the standard regarding ADL? Should all the functions from parent namespaces of the argument be found, or only the functions available in the (nested) namespace of the argument + the global functions?

This program has been tested on MSVC 2008 (and compiles with SP but not without...)

like image 294
DocZeD Avatar asked May 12 '11 09:05

DocZeD


1 Answers

According to the standard, ADL works (modulo a couple of special rules) "as if" the function name were preceded by the namespace; in your last line, lookup should precede as if you'd written A::B::scope. Which does not look in the surrounding namespaces.

Note that even within namespace A::B, there would be no ambiguity; in A::B, A::B::scope hides A::scope. Unqualified name lookup stops in the scope where it first finds the name.

like image 188
James Kanze Avatar answered Nov 09 '22 03:11

James Kanze