Почему GCC позволяет вызывать эту функцию, не используя ее пространство имен?

Possible Duplicate:
What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")?
Why does C++ parameter scope affect function lookup within a namespace?

Сегодня я испытал это странное поведение. Сначала я могу вызвать странную Fn без using namespace Strange, но не разрешаю вызывать странную Fn2 Почему?

namespace Strange
{
    struct X
    {
    };
    void strangeFn(X&) {}
    void strangeFn2(int) {}
}

int main()
{
    Strange::X x;
    strangeFn(x);    // GCC allows calling this function.
    strangeFn2(0);   // Error: strangeFn2 is not declared in this scope.
    return 0;
}

Как компиляторы C++ разрешают область действия символов?

Ответ 1

Это называется Поиск зависимых аргументов (или поиск Koenig)

В принципе, если символ не может быть разрешен, компилятор будет искать пространство имен (ов) аргумента (ов).

Второй вызов функции завершается с ошибкой, потому что strangeFn2 не отображается в текущем пространстве имен, и не определено в пространстве имен этого типа параметра (int)

Вы можете видеть, как это хорошо работает с функциями оператора:

 std::complex<double> c, d;
 c += d; // wouldn't really work without ADL

или вездесущие операторы iostream:

 std::string s("hello world");
 std::cout << s << std::endl; // Hello world would not compile without ADL...

Для удовольствия, это то, что мир привет будет выглядеть без ADL (и без ключевого слова using...):

 std::string s("hello world");
 std::operator<<(std::cout, s).operator<<(std::endl); // ugly!

Есть тенистые угловые случаи с ADL и разрешением перегрузки при наличии шаблонов функций, но я оставлю их вне области ответа на данный момент.