Trying to define a generic template operator for all container classes

S

Shriramana Sharma

Hello.

I am trying to define an operator<< in my program such that for any container_template_type and value_type, if con is an object of type container_template_type<value_type> and val1, val2, val3 are objects of type value_type, I can chain adding the objects to the container:

con << val1 << val2 << val3 ;

So I tried defining it as:

template < typename C, typename V >
inline C<V> &
operator << ( C<V> & con, const V & val ) { con.push_back(val) ; return con; }

but both GCC 4.8.1 and Clang 3.2 complain about this. GCC says "error: ‘C’ is not a template" and Clang says "error: expected unqualified-id".

I am not sure how to tell the compiler that C is a template type. Please help.

The code:

# include <iostream>
# include <vector>

template < typename C, typename V >
inline C<V> &
operator << ( C<V> & con, const V & val ) { con.push_back(val) ; return con; }

int main ()
{
vector<int> v ;
v << 1 << 2 << 3 ;
for ( int i = 0 ; i < v.size() ; ++i ) std::cout << v << ' ' ;
std::cout << std::endl ;
}
 
S

Shriramana Sharma

template < typename C, typename V >
inline C<V> &
operator << ( C<V> & con, const V & val ) { con.push_back(val) ; return con ; }

I had to do:

template < template<typename,typename> class C, typename V, typename A >
inline C<V,A> &
operator << ( C<V,A> & con, const V & val ) { con.push_back(val) ; return con ; }

to indicate that C is a template class taking two typename template arguments (the second being the allocator which apparently one can't avoid specifying even though it is mostly (?) not used.
 
N

Nobody

I am trying to define an operator<< in my program such that for any
container_template_type and value_type, if con is an object of type
container_template_type<value_type> and val1, val2, val3 are objects of
type value_type, I can chain adding the objects to the container:

con << val1 << val2 << val3 ;

So I tried defining it as:

template < typename C, typename V >
inline C<V> &
operator << ( C<V> & con, const V & val )

Why not just take the complete container type as a parameter and use its
value_type member:

template < typename C >
inline C &
operator << ( C & con, const typename C::value_type & val ) {

This way, it doesn't matter how many parameters the container template has.

Or even just:

template < typename C, typename V >
inline C &
operator << ( C & con, const V & val ) {

This way the container doesn't even need to be a template.

The downsides are that passing a value of a convertible type will result
in an extra instantation for that type, with the conversion being
performed at the .push_back() call, and that passing a value of a
non-convertible type will result in a messier error message.
 
S

Shriramana Sharma

Hello thanks for your reply. Comments inline:

Why not just take the complete container type as a parameter and use its
value_type member:

template < typename C >
inline C &
operator << ( C & con, const typename C::value_type & val ) {
This way, it doesn't matter how many parameters the container template has.

This method seems OK for inserting values into containers.
Or even just:
template < typename C, typename V >
inline C &
operator << ( C & con, const V & val ) {
This way the container doesn't even need to be a template.

This method will work fine if you don't have any iostreams in your program, because if you do, then any attempt to write to an ostream using the operator<< will call this template because it would fit to the described pattern.

As a related point, it would seem that if I want to write a template to dump the contents of a container to an ostream, it is not possible for me to avoid the template<typename,typename> class thing:

template < template<typename,typename> class C, typename V, typename A >
inline ostream & operator << ( ostream & os, const C<V,A> & con )
{
for ( typename C<V,A>::const_iterator it = con.begin() ; it != con.end() ; ++it ) os << *it << ' ' ;
os << endl ;
return os ;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top