Компилятор не может вывести T, однако, когда вы делаете его другом, он находит его через ADL.
Я изменил код на следующее:
#include <iostream>
using namespace std;
template< class T >
struct Foo {
struct Bar {
Bar ( const T &t ) : otherT_( t ) {}
T otherT_;
friend std::ostream& operator << (std::ostream& os, const Bar &bar )
{ return os; }
};
Foo ( const T &t ) : myT_( t ) {}
T myT_;
};
int main() {
Foo< int > foo( 5 );
Foo< int >::Bar bar( 7 );
std::cout << bar << std::endl;
return 0;
}