I just came across an interesting behavior with a search argument dependent, which I don't quite understand:
#include <iostream> namespace a { struct Foo { Foo(int v1, int v2) : v1(v1), v2(v2) { } int v1,v2; }; } namespace b { template <typename T> struct Baz : T { using T::T; }; } namespace c { using Foo = ::b::Baz< ::a::Foo>; // (1) NOT FOUND BY ADL // std::ostream& operator << (std::ostream& os, const Foo& foo) // { // return os << foo.v1 << "," << foo.v2; // } } namespace b { // (2) FOUND BY ADL std::ostream& operator << (std::ostream& os, const ::c::Foo& foo) { return os << foo.v1 << "," << foo.v2; } } int main() { c::Foo foo(1,2); // Variant (1): ADL fails: should it not find // c::operator<<(std::ostream&, const Foo&) ? // Variant (2) compiles std::cout << "foo: " << foo << std::endl; }
I realized that c::Foo is actually b::Baz<...> , so it makes some sense that ADL finds a statement when I define it inside namespace b . But it seems uninteresting that the statement definition inside namespace c does not work, since c::Foo should (IMHO) allow the compiler to execute ADL inside namespace c .
Why is this not so? What is the meaning of this?
source share