Jade Kim
Jade Kim

Reputation: 1

c++ template specialization of template container

what i would do is like ...

template < template <typename ... > typename __Container, typename ... __Args >
ostream& operator<<(ostream& os, __Container<__Args ...> const& rhs){
  stringstream ss;
  int i = 0;
  for (const auto& it : rhs) 
    ss << "idx[" << i << "] " << it << "\n";
  return os << ss.str();
}

/// 
/// ... and something template specialization code
/// 

int main (){
  std::vector<int> vec_data = { ... };
  std::cout << vec_data << std::endl; 

  std::deque<int> dq_data = { ... };
  std::cout << dq_data << std::endl; 

  std::map<std::string, double> map_data = { {}, {}, {}, ... };
  std::cout << map_data << std::endl; 


  return 0;
}

in this example, deque and vector are not a problem, but when i tried to struggle to specialize std::map i dumped it. is there any possible way to do it?

Upvotes: 0

Views: 133

Answers (1)

HolyBlackCat
HolyBlackCat

Reputation: 96951

Function templates can't be partially specialized, but can be overloaded:

template <typename ...P>
std::ostream &operator<<(std::ostream &os, const std::map<P...> &map)

But it's not the best idea, because you'd also have to specialize for std::multimap and std::unordered_[multi]map, and any non-standard containers you encounter in the future.

Instead you could create a function to print the single element, and overload it for std::pair (which is the element type of maps). Then call it from your operator.

There are more problems with the code:

  • Operators should only be overloaded where ADL can find them. Otherwise you won't be able to call them from some places (from any namespace that defines any operator<<; or from a template function defined above your operator).

    Since the only suitable namespace here would be std, and adding declarations there is not allowed, you shouldn't create such operator in the first place. Write a function instead.

  • Identifiers containing __ or starting with _[A-Z] are reserved, don't use them.

  • The operator<< should accept any basic_ostream<...> to support wide streams.

  • stringstream should be ostringstream, or removed altogether (print directly to the ostream).

Upvotes: 1

Related Questions