The following code fails to compile
namespace A {
using C = std::vector<std::string>;
std::ostream& operator << (std::ostream& lhs, const C& rhs) {
lhs << 5;
return lhs;
}
}
int main()
{
A::C f;
std::cout << f;
return 0;
}
with the error
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'A::C' (or there is no acceptable conversion)
Obviously it cant find the << operator presumably due to considering C to be a class from the std namespace. Is there some way to ensure the compiler finds this operator or otherwise work around the problem?
A::C
is just a type alias, and aliases are transparent. They don't "remember" where they came from. When we do argument-dependent lookup and figure out what the associated namespaces are, we only consider the associated namespaces of the types - not the alias that got us there. You can't just add associated namespaces to existing types. The specific associated namespace of f
(which is of type std::vector<std::string>
) is std
, which doesn't have an operator<<
associated with it. Since there's no operator<<
found using ordinary lookup, nor is there one found using ADL, the call fails.
Now, I said you can't just add associated namespaces to existing types. But you can of course just create new types:
namespace A {
struct C : std::vector<std::string> { };
}
or:
namespace A {
// template parameters are also considered for associated namespaces
struct S : std::string { };
using C = std::vector<S>;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With