Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template classes as template parameters

Tags:

c++

templates

How to define a function template-ed on a container and a type?

For example, overload insertion operator to stream all the elements of a vector, list, or, forward iterator container:

using namespace std;

#include <iostream>
#include <vector>
#include <list>


//...
//...the second argument is a container template-ed on type T
//...
template <typename T,template <typename U> class C>
ostream&
operator<<
  (ostream& p_os,const C<T>& p_c)
{
  for(typename C<typename T>::const_iterator cit=p_c.begin();cit!=p_c.end();++cit)
  {
    p_os.operator<<(*cit);
  }
  return p_os;
}

int
main
  ()
{
  vector<int> v;
  cout << v << endl;
  list<int> l;
  cout << l << endl;
  return 0;
}

This does not compile on g++ 4.9. What is wrong? How is it done?

like image 888
silvermangb Avatar asked May 14 '26 10:05

silvermangb


1 Answers

Why not just pass the container type as template parameter, and find out the element type from it? In your example code you don't even need the element type:

template <typename C>
ostream&
operator<<
  (ostream& p_os,const C& p_c)
{
  typedef typename C::value_type element_type; // if needed
  for(typename C::const_iterator cit=p_c.begin();cit!=p_c.end();++cit)
  {
    p_os.operator<<(*cit);
  }
  return p_os;
}

(Although it might be unwise to use this for global functions like this without some enable_if trickery, since it will otherwise match any argument.)

EDIT: You could for example attempt to restrict this to classes with a nested value_type (which all containers have):

template <typename C, typename T = typename C::value_type>
ostream&
operator<<
  (ostream& p_os,const C& p_c)
like image 145
Alan Stokes Avatar answered May 16 '26 00:05

Alan Stokes