1

I previously overloaded the << operator for a std::map using template for a std::map<std::string, int>

template <typename T, typename S> 
std::ostream & operator<<(std::ostream & os, const std::map<T, S>& v) 
{ 
    for (auto it : v)  
        os << it.first << " : " << it.second << "\n"; 

    return os; 
} 

How can a template be written if the map, for instance, was std::map< std::string, std::vector<int> >?

andres
  • 301
  • 6
  • 21

2 Answers2

2

There are several options for.

At first you could just provide a separate operator<< overload for std::vector, e. g.:

template <typename T>
std::ostream& operator<< (std::ostream& s, std::vector<T> const& v)
{ /* your generic implementation */ return s; }

It will then be called for every vector in your map:

os << it.first << " : " << it.second << "\n";
//                           ^ here...

I consider this the cleanest solution – but if it is too generic and you need something really different only for this specific map type, then you could either provide a separate overload for exclusively this type of map:

std::ostream& operator<<
        (std::ostream& s, std::map<std::string, std::vector<int>> const& m)
{ /* your specific implementation */ return s; }

or, alternatively, specialise your operator for it:

template <>
std::ostream& operator<< <std::string, std::vector<int>>
        (std::ostream& s, std::map<std::string, std::vector<int>> const& m)
{ /* your specific implementation */ return s; }
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
1

Is it possible? Yes, you could write the code.

Is it allowed? No, it's undefined behavior to extend the std namespace with your own symbols unless explicitly specified.

Looking at your current approach, I wouldn't overload the existing method. I would provide a new method for the pair.

JVApen
  • 11,008
  • 5
  • 31
  • 67
  • 1
    Where would we extend `std` namespace if we provide additional overloads in global namespace? Apart from, this is only half of the truth, as there is an exception: it is allowed to specialise existing templates within namespace `std`. – Aconcagua Jan 15 '19 at 06:49
  • 1
    To get the ADL correct, you have to define the operator in std. No, it is only allowed to specialize when explicitly permitted, like `std::hash`, you can't do so for `std::basic_string` – JVApen Jan 15 '19 at 06:56
  • If we rely on ADL, already the initial template fails - but if defined in global namespace, we do not rely on... – Aconcagua Jan 15 '19 at 07:19