Overload operator<< for ostream and wostream

Hi all.

Let's say I have a class, Foo, that I want to be streamable to an ostream. So I write this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string>
#include <iostream>

class Foo {
private:
	std::string n_;
public:
	Foo( const std::string& n ) : n_( n ) {}
	const std::string& n() const { return n_; }
};

ostream& operator<<( ostream& os, const Foo& foo ) {
	return os << foo.n();
}


But now I feel like I want it to be able to work with both ostream and wostream, and this is where my issue arises. I could always just write another class called WFoo that replaces the string with wstring and ostream with wostream, but that seems like a waste of time and typing since it will be the exact code just with different types.
So then I thought I could template the class like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include <string>
#include <iostream>

template <typename charT>
class BasicFoo {
private:
	std::basic_string<charT> n_;
public:
	BasicFoo( const std::basic_string<charT>& n ) : n_( n ) {}
	const std::basic_string<charT>& n() const { return n_; }
};

/*
***Here is the problem****
basic_ostream<charT>& operator<<( basic_ostream<charT>& os, const BasicFoo<charT>& foo ) {
	return os << foo.n();
}*/

typedef BasicFoo<char> AFoo;
typedef BasicFoo<wchar_t> WFoo;


Since operator<< isn't a member of the class, it doesn't know what the template parameter is, so I still have a problem of how to accept ostream and wostream. Any ideas on how to implement this would be greatly appreciated.

Thanks
Last edited on
1
2
3
4
5
6
7
template< typename charT >
class BasicFoo {
   friend template< typename charT, typename Traits > inline
   std::basic_ostream<charT, Traits>& operator<<( 
      std::basic_ostream<charT, Traits>& os, const BasicFoo& )
      { return os << ... ; }
};


I could not get the above one to compile.
The following seems to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include <string>
#include <iostream>

template <typename charT> class BasicFoo 
{
  private:
    std::basic_string<charT> n_;
  public:
    BasicFoo( const std::basic_string<charT>& n ) : n_( n ) {}
    const std::basic_string<charT>& n() const { return n_; }

    template< typename charT > friend
    std::basic_ostream< charT> & operator << ( std::basic_ostream< charT >& os, const BasicFoo& f )
    { return os << f.n().c_str(); }
};


typedef BasicFoo<char>    AFoo;
typedef BasicFoo<wchar_t> WFoo;

int main()
{
  // I compiled with ASCII (vs. UNICODE)

  AFoo fa( "AAA" );
  // This will print out the string AAA
  cout << fa << endl; 

  WFoo fw( L"WWW" );
  // This will print out the address
  cout << fw << endl; 
}


Output:


AAA
002DF8B8

Topic archived. No new replies allowed.