C++ ADL во вложенных пространствах имен с функцией шаблона

У меня вопрос относительно стандартного разрешения ADL в C++.

Вот пример кода, объясняющий мой запрос:

#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()
}

Итак, мой вопрос: каков стандарт в отношении ADL? Должны ли быть найдены все функции из родительских пространств имен аргумента или только функции, доступные в (вложенном) пространстве имен аргумента + глобальные функции?

Эта программа была протестирована на MSVC 2008 (и компилируется с SP, но не без...)


person DocZeD    schedule 12.05.2011    source источник
comment
Ваш код даже не скомпилируется ЛЮБЫМ компилятором, так как A::scope(), который не принимает никаких параметров, не существует, но вы вызываете эту функцию.   -  person Nawaz    schedule 12.05.2011
comment
Один компилятор старый, а другой новый, или они от разных производителей?   -  person Bo Persson    schedule 12.05.2011
comment
@Bo Persson - › Оба компилятора одинаковы, т. Е. MSVC поставляется с Visual Studio 2008, но один с последними установленными обновлениями (работает), а другой нет (ошибка компиляции)   -  person DocZeD    schedule 12.05.2011


Ответы (1)


Согласно стандарту, ADL работает (по модулю нескольких специальных правил) "как если бы" имени функции предшествовало пространство имен; в вашей последней строке поиск должен предшествовать, как если бы вы написали A::B::scope. Который не смотрит в окружающие пространства имён.

Обратите внимание, что даже внутри пространства имен A::B не будет двусмысленности; в A::B A::B::scope скрывает A::scope. Поиск неполного имени останавливается в той области, в которой он впервые находит имя.

person James Kanze    schedule 12.05.2011
comment
Спасибо, Джеймс, это именно то, о чем я думал :) Итак, чтобы продолжить, мой код должен скомпилироваться без какой-либо ошибки компилятора, вызванной двусмысленностью... опять проблема соответствия стандарту из MSVC, не так ли:/ - person DocZeD; 12.05.2011
comment
@DocZeD Просто любопытно, а какая версия VC? - person James Kanze; 12.05.2011