2015-12-31 6 views
2

Вот код:Вложенные Классы и ADL

namespace Namespace 
{ 
    struct L0 
    { 
     enum SomeEnum 
     { 
      EnumVal 
     }; 

     struct L1 
     { 
      friend void f(SomeEnum) 
      { 
       std::cout << "f()" << std::endl; 
      } 
     }; 

     friend void g(SomeEnum) 
     { 
      std::cout << "g()" << std::endl; 
     } 
    }; 
} 

int main() 
{ 
    f(Namespace::L0::EnumVal); // error: f not defined 
    g(Namespace::L0::EnumVal); // good 
} 

Идея заключается в том, чтобы сделать компилятор найти F() и г() через ADL.

Однако этот код не скомпилирован с gcc или clang. Похоже, что подобный код компилировался под MSVC.

Возможно, мне что-то не хватает, но я действительно не понимаю, что не так с кодом, и не так ли вообще. Было бы хорошо, если бы кто-то мог пролить свет на этот.

PS. С новым годом :)

ответ

2

SomeEnum не является членом L1, поэтому ADL не находит функцию, определенную в L1.

Я считаю, что это цитата искали:

Имени первый заявил в другом объявлении в классе или шаблон класса X становится членом внутренних ограждающего пространства имен X, но не доступный для поиска (за исключением зависящего от аргумента поиска, который рассматривает X), если не указано соответствующее объявление в области пространства имен. Подробнее см. в пространствах имен.

+0

Не следует ли также исследовать самое внутреннее пространство имен SomeEnum? – dsi

+0

@dsi, нет, почему вы так думаете? – SergeyA

+0

Я полагался на cppreference.com, который говорит: «4). Для аргументов типа перечисления в набор добавляется пространство имен, в котором определено перечисление. Если тип перечисления является членом класса, этот класс добавляется к набор." – dsi