Подтвердить что ты не робот

Функции с аргументами класса просачиваются из пространства имен?

У меня есть небольшой фрагмент кода для вашего рассмотрения, который меня очень озадачивает. Странно, что он компилируется как на Sun Studio, так и на GCC, хотя я думаю, что это не должно быть.

Рассмотрим это:

namespace name
{
  class C
    {
      int a;
    };

  void f(C c);
  void g(int a);
}

int main(int argc, char** argv)
{
  name::C c;

  name::f(c); 
  f(c);  // <--- this compiles, strangely enough

  name::g(42);
  // g(42);  <--- this does not, as I expected
}

Аргумент класса из одного и того же пространства имен заставляет функцию f "просачиваться" из пространства имен и быть доступной без name::.

Есть ли у кого-нибудь объяснения? Это, конечно, я, а не компилятор, здесь не так.

4b9b3361

Ответ 1

Он называется зависимый от аргумента поиск (или поиск Koenig). Короче говоря, компилятор будет искать функцию в пространствах имен, которые являются пространствами имен типов аргументов.

Ответ 2

Это Поиск зависимых от аргументов, a.k.a. ADL, a.k.a. Koenig lookup. Это было изобретено для того, чтобы операторы работали, как ожидалось, например:

namespace fu {
    struct bar { int i; };
    inline std::ostream& operator<<( std::ostream& o, const bar& b ) {
        return o << "fu::bar " << b.i;
    }
}

fu::bar b;
b.i = 42;
std::cout << b << std::endl; // works via ADL magic

Без ADL вам придется либо явно привести оператор вывода с уродливым using fu::operator<<;, либо использовать еще более грубый явный вызов:

fu::operator<<( std::cout, b ) << std::endl;

Ответ 3

Это связано с "зависимым от аргумента поиска". Удаление const не изменит поведение, которое вы видите. Чтобы продемонстрировать, что это ADL, попробуйте переместить St-структуру за пределы пространства имен...

struct St
{
   int a;
};

namespace name
{
  void f(const St& st);
  void g(int a);
}

int main(int argc, char** argv)
{
  St st;

  name::f(st); 
  f(st);  // <--- now you will get the expected compile error

  name::g(42);
  // g(42);  <--- this does not, as I expected
}

Ответ 4

Это вызвано зависимым от аргумента поиска.