I have the following setup:
template< class T >
struct Foo {
struct Bar {
Bar ( const T &t ) : otherT_( t ) {}
T otherT_;
};
Foo ( const T &t ) : myT_( t ) {}
T myT_;
};
Now, I want to make instances of Foo< T >::Bar
streamable to std::cout and friends. I tried this:
template< class T >
std::ostream& operator<< ( std::ostream &os,
const typename Foo< T >::Bar &bar ) {
os << "<bar: " << bar.otherT_ << ">";
return os;
}
But the following code does not compile:
Foo< int > foo( 5 );
Foo< int >::Bar bar( 7 );
std::cout << bar << std::endl;
I guess that the compiler is not able to deduce the type T
or something. Is there a way to make such instances of the nested class behave well with operator<<
?
Thank you!
std::cout << bar
? Or can I make the one-to-one mapping mentioned in the linked answer explicit? – BollenT
inFoo<T>::Bar
is a non-deduced context, see §14.8.2.5/5. As others have pointed out, making the function a friend works (because the resulting function is not a template, so no type deduction is needed). – StigFoo<T>::Bar = X
forT
givenX
. – ImpoverishT
that satisfy the equation, with no obvious ordering among them...? – ImpoverishFoo<int>::Bar
, so there's not really an ambiguity. Where it becomes tricky is whenBar
is a typedef. – Stigtemplate <> struct Foo<int> { typedef int Bar; };
. Suddenly you've brokenstd::cout << 10;
... – Impoverishstd::cout << 10
becomes ambiguous is secondary; this can happen whether templates are involved or not. The fact that the compiler might have to analyze the entire program to find the correct overload is more of an issue. – Stig