The problem is your std::istream& operator>>( std::istream&is, par & p )
is not in the namespace std, or in any of the associated namespaces, which is where you are going to search following the rules of the "Argument-dependent lookup" [ADL] ( link )
There is a trick that allows the ADL mechanism to find your overloaded operator, using its own type:
struct P : par {
using par::pair;
};
Putting P instead of pair, it has to work. Something like this:
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <sstream>
using namespace std;
using word = std::string;
using number = float;
using par = std::pair<word, number>;
using pares = std::vector<par>;
struct P : par {
using par::pair;
};
std::ostream& operator<<(std::ostream&os, P const&p)
{
os << p.first << " " << p.second;
return os;
}
std::istream& operator>>(std::istream& is, P& p)
{
is >> p.first >> p.second;
return is;
}
int main()
{
ostringstream os("qwe 123\nasd 321", ios::out | ios::in);
istream in(os.rdbuf());
std::copy(std::istream_iterator<P>(in), std::istream_iterator<P>(),
std::ostream_iterator<P>(std::cout, "\t"));
return EXIT_SUCCESS;
}