I'm trying to improve my understanding of templates. As a test I'd like to overload the stream operator<<
so that it will operate on a templated class together with the (templated) basic_ostream
from the STL. Here is a minimal example:
#include <iostream>
using namespace std;
//Forward declarations
template< typename T >
class Container;
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container );
//Definitions
template< typename T >
class Container
{
public:
Container( T a_value ): value( a_value ){}
private:
T value;
template< typename charT, typename traits >
friend basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container );
};
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container )
{
out << a_container.value;
return out;
}
//Main
int main( void )
{
Container< int > my_container( 42 );
cout << my_container;
return 0;
}
However, when I try and compile this code the linker cannot seem to find the overloaded function:
/home/Ae6PGM/cc5xj2iM.o: In function `main':
prog.cpp:(.text.startup+0x21): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <char, std::char_traits<char> >
(std::basic_ostream<char, std::char_traits<char> >&, Container<int> const&)'
collect2: error: ld returned 1 exit status
I can fix this error if I make every template instance of my overloaded operator<<
a friend, but it seems more correct if only instances which match the container type are friends. Here is a link to the working, but incorrect verion: http://ideone.com/DNQzlB.
Another alternative is to put the function definition inside the class declaration, but I'd like to avoid this if possible.
There is a similar, but slightly more simple question here. There is a great answer, but I can't figure out how to adapt it to my problem.
Thanks,
Andrew