Ответ 1
Он называется зависимый от аргумента поиск (или поиск Koenig). Короче говоря, компилятор будет искать функцию в пространствах имен, которые являются пространствами имен типов аргументов.
У меня есть небольшой фрагмент кода для вашего рассмотрения, который меня очень озадачивает. Странно, что он компилируется как на 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::
.
Есть ли у кого-нибудь объяснения? Это, конечно, я, а не компилятор, здесь не так.
Он называется зависимый от аргумента поиск (или поиск Koenig). Короче говоря, компилятор будет искать функцию в пространствах имен, которые являются пространствами имен типов аргументов.
Это Поиск зависимых от аргументов, 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;
Это связано с "зависимым от аргумента поиска". Удаление 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
}
Это вызвано зависимым от аргумента поиска.