I have this snippet of code and I do not understand why the std::cout line is not compiling... The argument lookup / template argument inferencing seems correct...
#include <iostream>
template<typename T>
struct A
{
struct M1
{
T x;
};
};
template<typename T>
std::ostream &operator<<(std::ostream &os, typename A<T>::M1 const &o)
{
os << o.x;
return os;
}
int main()
{
A<int>::M1 a;
std::cout << a; // This line fails
return 0;
}
BTW I'm trying to do this without a declaring operator<<() as an inline function.
Your problem is that T
is in a non deduced context. C++ will only simple pattern match, it will not invert possibly arbitrary type maps.
Imagine there was a specialization of A<void>
that set using M1=A<int>::M1
. Now both int
and void
are valid T
for your <<
. As the problem is intractible in general, C++ refuses to even try: you can only pattern match on direct template arguments of your argument types.
To do what you really want:
template<typename T>
struct A {
struct M1 {
T x;
friend std::ostream& operator<<(std::ostream& os, M1 const& m1){
return os << m1.x;
}
};
};
Learn to love Koenig operators.