Needless to say any more than the following code:
#include <utility>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
typedef pair<char, char> PAIR;
ostream& operator <<(ostream& os, const PAIR& r)
{
return os << r.first;
}
int main()
{
vector<PAIR> coll;
cout << coll[0]; // OK.
// The following line will cause a compilation error! Why???
copy(coll.begin(), coll.end(), ostream_iterator<PAIR>(cout));
}
The problem is that the name lookup does not find your operator<<(ostream& os, const PAIR& r)
. The code that tries to invoke the operator<<
is in somewhere inside the ostream_iterator<>
which is itself inside the std
namespace. The name lookup looks around for the right function inside ostream_iterator<>
and the std
namespace; the argument dependent lookup does not help here because both of the parameters are in the std
namespace, too.
So, my suggestion is (1) either to wrap your operator into namespace std { }
, but that is UB, IIRC. Or (2) create a struct inheriting from std::pair
to define a new type in your namespace, and using the ADL to find your operator<<()
.
UPDATE:
My 3rd suggestion is to use a custom manipulator to print out the pair.
As for my 2nd suggestion, if you can use C++11, inheriting from std::pair
should be easy (untested):
struct PAIR : std::pair
{
using std::pair::pair;
};
If you cannot use C++11, then I suggest using a custom manipulator.
This is a common problem : in a word, your operator<<
is not seen when instantiating std::ostream_iterator
.
During instantiation, name lookup attempts to find an operator<<
in the namespace std
. Candidates will be found, so no other namespaces will be considered (and, particularly, not the global namespace). Then, overload resolution comes into play : none of the overload matches the argument type, so compilation fails. Note that argument dependent lookup is not of any help here as std::pair
also is in namespace std
.
You have two solutions :
operator<<
in namespace std { }
, although you should know that this is illegal according to the standard (17.4.3.1)std::copy
for this task and use std::for_each
(either with an 'old-fashioned' functor or lambda)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With