Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

pair inserter

36 views
Skip to first unread message

alex.ai...@inphinity.com

unread,
Jan 16, 2001, 3:24:29 PM1/16/01
to
What's wrong with the next code?

//////
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/

Alex Mitrofanov

unread,
Jan 16, 2001, 3:41:59 PM1/16/01
to
In article <942alj$9qt$1...@nnrp1.deja.com>,

Hi Alex,
Your map<int, int> instantiation doesn't correspont pair<int const,int>.

Regards,

John Harrison

unread,
Jan 16, 2001, 3:50:29 PM1/16/01
to

<alex.ai...@inphinity.com> wrote in message
news:942alj$9qt$1...@nnrp1.deja.com...

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

Tom

unread,
Jan 16, 2001, 4:09:36 PM1/16/01
to
Previously, John Harrison wrote in comp.lang.c++:

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

Ron Natalie

unread,
Jan 16, 2001, 4:16:41 PM1/16/01
to

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.

.

Tom

unread,
Jan 16, 2001, 4:50:50 PM1/16/01
to
Previously, Ron Natalie wrote in comp.lang.c++:

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

0 new messages