//////
map< int, int> vv;
ostream& operator<<( ostream&, pair<int const,int>);
copy( vv.begin(), vv.end(),
ostream_iterator< pair<int const,int> >(cout));
///////
From MSVC++ 6.0 I got a message
error C2679: binary '<<' :
no operator defined which takes a right-hand operand of type
'const struct std::pair<int const ,int>'
(or there is no acceptable conversion)
while compiling class-template member function
'class std::ostream_iterator
<struct std::pair<int const ,int> const ,
char,
struct std::char_traits<char> >
&__thiscall
std::ostream_iterator<struct std::pair<int const ,int>
const ,char,struct std::char_traits<char> >
::operator =(const struct std::pair<int const ,int> &)'
Thanks,
Alex
Sent via Deja.com
http://www.deja.com/
Hi Alex,
Your map<int, int> instantiation doesn't correspont pair<int const,int>.
Regards,
I've come across similar problems before on MSVC++. It goes away if you put
the operator<< in the std namespace, i.e.
namespace std
{
ostream& operator<<( ostream&, const pair<int const,int>);
}
Seems like a compiler bug.
john
No it's not, it's Koenig lookup (aka argument dependent lookup, ADL) in action.
Shockingly enough, MSVC actually has ADL implemented for operators (though not
functions), and that is what causes the problem.
std::pair<int const, int> is from std
std::ostream is from std
inside the std::ostream_iterator, where operator<< is called, is in std.
-> only std is searched for the operator<<
But the operator<< is in global, and hence is not found.
The above fix is illegal in the strict sense since there are only certain
things that you are allowed to add to std (e.g. specializations of std::swap).
A legal solution is to use a proxy class:
template <class T1, class T2>
class pair_printer
{
public:
typedef std::pair<T1, T2> pair_type;
pair_printer(pair_type const& p)
:m_p(p);
friend std::ostream& operator<<(std::ostream& os, pair_printer const& pp)
{
return os << '(' << pp.m_p.first << ',' << pp.m_p.second << ')';
}
private:
pair_type const& m_p;
};
copy( vv.begin(), vv.end(),
ostream_iterator< pair_printer<int const,int> >(cout));
Now, operator<< and pair_printer are in the same namespace, so operator<< will
be found.
Tom
Tom wrote:
> > I've come across similar problems before on MSVC++. It goes away if you put
> > the operator<< in the std namespace, i.e.
> >
> > namespace std
> > {
> > ostream& operator<<( ostream&, const pair<int const,int>);
> > }
> >
> > Seems like a compiler bug.
>
> No it's not, it's Koenig lookup (aka argument dependent lookup, ADL) in action.
> Shockingly enough, MSVC actually has ADL implemented for operators (though not
> functions), and that is what causes the problem.
And you don't characterize the lack of Koenig lookup on member functions to
be a bug? Microsoft does.
.
Yes I do. But I was saying that the existence of Koenig lookup for operators in
MSVC6 is not a bug. The bug was not relevent to the OP's problem, nor to John's
solution.
Tom