Two words: name lookup.
Here is a simplified example of what you are trying to do, without any Standard Library headers required:
template <typename T> void f(T) { }
namespace ns {
class C { };
void f(int) { }
void test() { f(C()); } // doesn't work :'(
}
int main() {
f(ns::C()); // works! :-D
}
In this example, in main()
, the only f
that is found during normal name lookup is the function template in the global namespace, and it matches, so main
uses it (ns::f
is also found during argument-dependent lookup, but it isn't a match so the global f
is still selected during overload resolution).
In test
, however, the ns::f(int)
overload is found and name lookup stops. Namespaces are searched outwards, so ns
is searched first, then the global namespace, but name lookup stops once a name is found, so once ns::f(int)
is found, name lookup stops. Argument-dependent lookup also takes place and also finds ns::f(int)
, since C
is in namespace ns
, then ADL stops searching.
The same is true in your example: in main()
, the operator<<
overload is found, but inside of the std::ostream_iterator
, which is in the std
namespace, other <<
overloads are found, and so your overload is not found.
Your operator<<
overload would need to be in the std
namespace for it to work, but unfortunately you aren't allowed to add names to the std
namespace.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…