0

I have a function that prints generic container as following:

template<typename T>
void printContainer(std::ostream& out, const T& container)
{
    std::copy(std::begin(container),
              std::end(container),
              std::ostream_iterator<typename T::value_type>(out, " "));

}

This function works fine for vector, list, set, etc. However, for map it doesn't work because there is not operator<< for pair. So I added the following overloading of operator<<:

template <typename Key, typename Value>
ostream& operator<<(ostream& out, const pair<const Key, Value>& element)
{

    return out << "(" << element.first << "," << element.second << ")";
}

The following discussion also suggest that this is a legitimate solution: link to relevant post

However, I am getting the following compilation error:

Error   C2679   binary '<<': no operator found which takes a right-hand operand of type 'const std::pair<const _Kty,_Ty>' (or there is no acceptable conversion)    

I am looking at the type that the compiler claims is missing and at my implementation of operator<< for pair and they seem identical.

I tried to move operator<< code to hpp file, remembering that compilers tend to see one cpp file at time, but it didn't help.

Any suggestions would be appreciated...

Community
  • 1
  • 1
Victoriia
  • 105
  • 9
  • Your overload is not visible to `std::ostream_iterator` implementation, nor can it be found by argument-dependent lookup. It could probably be found if you place it into `std` namespace, but that's illegal for other reasons. It should also work for a map that has a user-defined class for a key or a value; then it'd be found by argument-dependent lookup. – Igor Tandetnik May 18 '17 at 14:09
  • @IgorTandetnik Thank you for your response. You are correct as the error points to a place into ostream_iterator. Do you have a suggestion how to solve this problem? Would greatly appreciate the help. – Victoriia May 18 '17 at 14:12
  • Another option is to not use `std::ostream_iterator` et al, but a hand-written loop that uses `<<` directly. Then name lookup would happen in the context of the global namespace, rather than from inside `std`. – Igor Tandetnik May 18 '17 at 14:15
  • @IgorTandetnik I would like to create one function that will handle all STL containers. Earlier today I tried to do it by overloading operator<< to take a container. However, this way proved to be problematic as I started getting "ambiguous" errors. In search of a solution I found the implementation with std::ostream_iterator which seemed to be working for other containers. Correct me if I am wrong but replacing it with hand-written loop seems to mean that I will need to have a separated print function for maps.... – Victoriia May 18 '17 at 14:20
  • @IgorTandetnik It was helpful of you to mention argument-dependent look up and namespaces. Helped me to understand more. – Victoriia May 18 '17 at 14:23
  • You can implement `printContainer` that doesn't use `std::copy` or `std::ostream_iterator`, but instead simply runs a loop from `std::begin(container)` to `std::end(container)` and outputs each element with `out << *iter;`. There's no dark magic in `std::copy` or `std::ostream_iterator`, they are simple wrappers over lower-level constructs. – Igor Tandetnik May 18 '17 at 14:24
  • @IgorTandetnik It worked!!! Thanks a lot. P.S.: what do you mean no dark magic? The whole compilation process is based on dark magic.... – Victoriia May 18 '17 at 15:11

0 Answers0