tags:

views:

105

answers:

1

I want to overload operator <<() for my own class that is also a template. My classes are as follows:

template<
    typename RefCountType,
    typename TraitsType = std::char_traits<char>,
    typename Allocator = std::allocator<typename TraitsType::char_type>
>
class rep {
    // ...
};

template<typename RepType>
class t_zstring {
    // ...
};

The code for operator<<() is:

template<
  typename CharType,
  typename TraitsType,
  typename Allocator,
  typename RefCountType,
  template<class,class,class> class RepType
>
inline std::basic_ostream<CharType,TraitsType>&
operator<<( std::basic_ostream<CharType,TraitsType> &os,
            t_zstring< RepType<RefCountType,TraitsType,Allocator> > const &s ) {
  return os << s.c_str();
}

The template code compiles just fine; however, when I attempt to use it like (with the code for the my_ref_count class elided):

typedef rep<my_ref_count> my_rep;
typedef t_zstring<my_rep> zstring;
zstring z;
cout << z; // ztest.cpp, line 201

I get (using g++ 4.2.1):

ztest.cpp:201: error: no match for ‘operator<<’ in ‘std::cout << z1’

How can I declare my operator<<() correctly so the compiler will find the correct match?

A: 

If you want to define the << operator for class t_zstring, I think it is easier to write:

template<typename OS, typename RepType>
OS& operator<<(OS &os, t_zstring<RepType> const &s ) 
{ 
  return os << s.c_str();
}
J. Calleja
Except that doesn't restrict the type of OS to be a std::basic_ostream.
Paul J. Lucas
Yes, you are right. As you suggested that g++ 4.2.1 may be broken, I thought an easier declaration may solve it.After all, restricting OS to std::basic_ostream is not always necessary.
J. Calleja