Overload operator for both std::vector and std::list

  • A+

I want to overload operator<< for both std::list and std::vector with the following code. But the two functions are almost the same. Is there any way to combine them, i.e., create a more generic overload?

#include <iterator> #include <iostream> #include <vector> #include <list>  template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {   if (!v.empty())     std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));   return out; }  template <typename T> std::ostream &operator<<(std::ostream &out, const std::list<T> &v) {   if (!v.empty())     std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));   return out; }  int main() {   std::cout << std::vector<int>({1, 2, 3, 4}) << std::endl;   std::cout << std::list<int>({1, 2, 3, 4}) << std::endl;   return 0; } 


You can use template with template arguments like in the following example:

template <typename T, typename A, template <typename X, typename Y> class C>  std::ostream &operator<<(std::ostream &os, const C<T,A> &container) {   if(!container.empty())     std::copy(container.begin(), container.end(), std::ostream_iterator<T>(os, " "));   return os; }  int main() {     list<int> l{1,2,3,4,5};      vector<string> v{"one","two","three"};     cout<<l<<endl<<v;      return 0; } 

Online demo.

Bu the way, you may find other example for working with templates of templates in this SO question.

But you have to be careful with this kind of construct:

  • it works only for containers defined with two template arguments (so ok for list and vectors; but not for sets or maps).
  • it might conflict with other template types using two arguments, for which there's no specialisation of the extractor.

Remark: If you look for a general purpose solution, you should better think of creating an adapter template that uses an iterator as parameter, and then write the general purpose extractor for this adaptor.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: