При поиске в зависимости от аргумента (правильное имя для поиска koenig) компилятор добавляет к перегруженной функции набор функций, которые объявлены в пространствах имен каждого параметра.
В вашем случае первый operator<<
объявлен в пространстве имен thesus::core,
, которое является типом аргумента, с которым вы вызываете оператор. Поэтому это operator<<
считается для ADL, потому что оно объявлено в связанном пространстве имен
Во втором случае operator<<
кажется объявленным в глобальном пространстве имен, которое не является ассоциированным пространством имен, поскольку параметр один имеет тип из пространства имен std
, а параметр 2 имеет тип из пространства имен theseus::core
.
На самом деле, вероятно, ваш 2-й operator<<
не объявлен в глобальном пространстве имен, так как это будет найдено при просмотре в родительских областях ... может быть, у вас есть что-то более похожее на это? Если вы можете разместить больше кода, мы можем дать лучший ответ.
Хорошо, я вспомнил, ADL не ищет в родительских областях, когда находит имя в текущей области. Таким образом, макрос повышения BOOST_TEST_MESSAGE
расширяется и включает в себя operator<<
, и в дереве областей действия есть некоторая нежизнеспособная operator<<
между выражением и глобальной областью действия. Я обновил код, чтобы проиллюстрировать это (надеюсь).
#include <iostream>
namespace NS1
{
class A
{};
// this is found by expr in NS2 because of ADL
std::ostream & operator<<(std::ostream &, NS1::A &);
}
// this is not seen because lookup for the expression in NS2::foo stops when it finds the operator<< in NS2
std::ostream & operator<<(std::ostream &, NS1::A &);
namespace NS2
{
class B
{};
// if you comment this out lookup will look in the parent scope
std::ostream & operator<<(std::ostream &, B &);
void foo(NS1::A &a)
{
std::cout << a;
}
}