简体   繁体   中英

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM