1

I am trying to use ostream_iterator for writing a vector of pairs to a file.ostream_iterator requires a template argument to be applied at the time of declaration. The vector is defined as-

vector<pair<string,long>> test;

When I pass pair as a template to the ostream_iterator it shows an error -

Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::pair<_Ty1,_Ty2>' (or there is no acceptable conversion) C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\iterator 531 1 wordsegmentation

What could be the correct argument in this situation?

Edit- Code Snippet

vector<pair<string,long>> t;
......
//t is filled up with elements 
ostream_iterator<pair<string,long>> output_iterator(out, "\n");
std::copy(t.begin(), t.end(), output_iterator);
code4fun
  • 2,661
  • 9
  • 25
  • 39
  • Show the actual code you're calling `ostream_iterator` with. – Yuushi Jun 06 '13 at 07:45
  • possible duplicate of [std::copy to std::cout for std::pair](http://stackoverflow.com/questions/634087/stdcopy-to-stdcout-for-stdpair) – Johan Lundberg Jun 06 '13 at 07:49
  • possible duplicate of [Pretty-print C++ STL containers](http://stackoverflow.com/questions/4850473/pretty-print-c-stl-containers) – juanchopanza Jun 06 '13 at 07:52
  • definitely duplicate of [Why does ostream_iterator not work as expected?](http://stackoverflow.com/questions/4447827) – djf Jun 06 '13 at 08:31

2 Answers2

3

There is NO operator << for std::pair. You cannot simply use ostream_iterator with std::pair.

You can use other things, or write class, that derived from pair, or that store pair and use it. You cannot write overloads in std namespace, since it leads to undefined behaviour and you cannot overload this operator in global namespace, since ADL will not find correct overload (if you use stl algorithms, like copy, ostream_iterator).

Simply, something like this will work well

#include <iostream>
#include <utility>
#include <algorithm>
#include <iterator>

int main()
{
   std::vector<std::pair<int, int>> vec =
   {
      {1,1},
      {2,2}
   };
   for (const auto& p : vec)
   {
      std::cout << p.first << " " << p.second << std::endl;
   }
}
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • I get the same error if my each element is a vector.Can you suggest an alternative to write such a variable to a file.I originally wanted to write hashmap to a file but this seemed easier .Thanks – code4fun Jun 06 '13 at 07:47
  • thanks.So,the pair I am actually using is pair> .How do you think should I store it so that I can correctly identify the vector when I am reading the file back. – code4fun Jun 06 '13 at 08:05
  • @code4fun it should be your decision. May be some tag, or delimiter, don't know. – ForEveR Jun 06 '13 at 08:10
  • can you explain why have used "const" for the auto reference variable in your code?I think that we can't declare it const.Thanks – code4fun Jun 09 '13 at 02:48
  • @code4fun auto deduce `p` to some type (`std::pair` here), `const auto&` means `const std::pair&` here. – ForEveR Jun 09 '13 at 13:37
1

You can simply overload std::ostream& operator<<:

std::ostream& operator<<(std::ostream& o, const pair<string,long>& p)
{
  return o << p.first << " " << p.second;
}

Or have a look at pretty print C++ containers.

Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480