ИСПРАВЛЕНИЕ : текст ниже основан на опыте работы с компиляторами семейства g ++. После комментария к ответу я перечитал стандарт (который гласит, что ADL будет использоваться поверх обычного поиска имени, а обычный поиск имени должен найти оператор <<). Я также попробовал с <a href="http://www.comeaucomputing.com/" rel="nofollow noreferrer"> comeau компилятором (самый стандартный совместимый компилятор, который я знаю), и символ найден. Это похоже на проблему с g ++ (пробовал версии 3.3, 4.1, 4.3).
Оригинальный ответ:
Поиск для поиска Коенинга (технически ADL: поиск, зависящий от аргумента).
Короткий ответ: если у вас есть следующий класс:
namespace test {
class A {};
}
оператор вставки потока должен быть определен как:
namespace test {
std::ostream& operator<<( std::ostream&, A const & );
}
Функции или операторы должны быть определены в том же пространстве имен, что и один из принимаемых им аргументов. (*)
Когда компилятор находит вызов функции, такой как:
namespace test2 {
void g() {
namespace1::class1 c1;
namespace2::namespace3::class2 c2;
f( c1, c2 );
}
}
он попытается найти функцию f в текущем пространстве имен (по месту вызова) или во вложенных пространствах имен типов c1 и c2 (namespace1, namespace2 :: namespace3), но он будет не пытайтесь использовать другие пространства имен в поиске.
(*) В этом случае вы в значительной степени ограничены пространством имен test , поскольку вам не разрешено добавлять функцию в пространство имен std (только для специализаций шаблонов).
Конец исходного сообщения .
Даже если, как отмечалось ранее, это может быть просто проблемой с компилятором, это обычное использование и рекомендуется определять все свободные функции, которые работают с определяемым пользователем типом в том же пространстве имен, что и сам тип.