Я недавно работал с некоторыми простыми типами для некоторого кода, который у меня есть, и перегружал оператор вставки для них, чтобы их можно было легко распечатать. Я натолкнулся на случай, когда я буквально получил тысячу строк компиляции. Упрощенная версия здесь:
#include <iostream>
#include <sstream>
#include <utility>
#include <string>
namespace ns{
template<typename KEY, typename VALUE>
using KeyValue = std::pair<KEY, VALUE>;
template<typename K, typename V>
inline std::ostream& operator<< (std::ostream& os, const KeyValue<K,V>& arg){
os << "Key: " << arg.first << " Value: " << arg.second;
return os;
}
}
struct Foo_t{
double a = 0;
};
inline std::ostream& operator<< (std::ostream& os, const Foo_t& f){
os << "a: " << f.a;
return os;
}
int main()
{
Foo_t foo{6.283185};
ns::KeyValue<std::string, Foo_t> foo_kv{"Foo_t", foo};
std::ostringstream oss;
oss << foo_kv;
std::cout << oss.str();
}
Оказывается, ошибка в том, что Foo_t
и его operator<<
не находятся в пространстве имен ns
. Если я добавлю их в пространство имен ns
и внесу коррективы в main, то все будет хорошо. Исходя из своего, по общему признанию, ограниченного знания, я бы подумал, что его найдут через ADL, но, похоже, это не так. Почему? Есть ли лучший способ исправить это, кроме простого добавления Foo_t
в пространство имен ns
?
Между прочим, тысяча строк puke компилятора была G CC, пытающейся помочь и перечисляющей все возможные перегрузки operator<<
, о которых она знала.