473,382 Members | 1,689 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

why doesn't this compile?

#include <map>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;

typedef map<int, int> Map;

ostream& operator<<(ostream& os, const Map::value_type& v);

int main()
{
Map m;
copy(m.begin(), m.end(),
ostream_iterator<Map::value_type>(cout, "\n"));
}

The error message is "no match for ostream << const pair<const int, int>&",
which I think I declared.

--
ES Kim
Jul 22 '05 #1
9 1397
ES Kim wrote:
#include <map>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;

typedef map<int, int> Map;

ostream& operator<<(ostream& os, const Map::value_type& v);

int main()
{
Map m;
copy(m.begin(), m.end(),
ostream_iterator<Map::value_type>(cout, "\n"));
}

The error message is "no match for ostream << const pair<const int, int>&",
which I think I declared.


The problem is in "argument-dependent name lookup". The operator << is
not found in the global namespace (where you declared it) becuase both
its operands (ostream and pair) are declared in 'std' namespace. The
work-around for this is to place your operator << in 'std' namespace.
Ugly, but works:

namespace std {
ostream& operator <<(ostream& os, const Map::value_type& v);
}

V
Jul 22 '05 #2
ES Kim wrote in news:cn**********@news1.kornet.net in comp.lang.c++:
#include <map>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;

typedef map<int, int> Map;

ostream& operator<<(ostream& os, const Map::value_type& v);

int main()
{
Map m;
copy(m.begin(), m.end(),
ostream_iterator<Map::value_type>(cout, "\n"));
}

The error message is "no match for ostream << const pair<const int,
int>&", which I think I declared.


Yep but ostream_iterator looks for this in:

- namespace std, by ADL as ostream and pair are declared there.
- namespace std, as ostream_iterator is defined there [1]
- namespace :: (global) as it containes std [1].

However in both non-ADL cases [1] the namespace is only searched
for declaration's that existed *prior* to the defenition of
ostream_iterator.

Your declaration/defenition was added *after* that point so
it isn't found.

Note if you make one of std::map's arguments a UDT then ADL
will find your declaration.

For those that don't know ADL = Argument Dependant Lookup.

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #3

"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@130.133. 1.4...
ES Kim wrote in news:cn**********@news1.kornet.net in comp.lang.c++:
#include <map>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;

typedef map<int, int> Map;

ostream& operator<<(ostream& os, const Map::value_type& v);

int main()
{
Map m;
copy(m.begin(), m.end(),
ostream_iterator<Map::value_type>(cout, "\n"));
}

The error message is "no match for ostream << const pair<const int,
int>&", which I think I declared.

Yep but ostream_iterator looks for this in:

- namespace std, by ADL as ostream and pair are declared there.
- namespace std, as ostream_iterator is defined there [1]
- namespace :: (global) as it containes std [1].

However in both non-ADL cases [1] the namespace is only searched
for declaration's that existed *prior* to the defenition of
ostream_iterator.

Your declaration/defenition was added *after* that point so
it isn't found.


That's amazing. I changed the OP's example slightly. On Comeau C++ this
compiles

#include <utility>
#include <iosfwd>

typedef std::pair<int, int> Pair;

std::ostream& operator<<(std::ostream& os, const Pair& v);

#include <map>
#include <iterator>
#include <iostream>
#include <algorithm>

int main()
{
std::map<int, int> m;
copy(m.begin(), m.end(),
std::ostream_iterator<Pair>(std::cout, "\n"));
}

but this (which is just a rearrangement) doesn't

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

typedef std::pair<int, int> Pair;

std::ostream& operator<<(std::ostream& os, const Pair& v);

int main()
{
std::map<int, int> m;
copy(m.begin(), m.end(),
std::ostream_iterator<Pair>(std::cout, "\n"));
}

Which means I think that predict what code will compile in cases like these
you have to known precisely what definitions are included by which header
files.

Note if you make one of std::map's arguments a UDT then ADL
will find your declaration.


Rob, you obviously have a thorough understanding of ADL (Koenig lookup I
still like to call it). How many other people do you find understand all the
subtleties? Do you think it is too complicated? Is it worth learning
properly, or can you just muddle through? Reading this thread has made me
all to aware that is exactly what I am doing.

john
Jul 22 '05 #4
John Harrison wrote:
[...]
Rob, you obviously have a thorough understanding of ADL (Koenig lookup I
still like to call it). How many other people do you find understand all the
subtleties? Do you think it is too complicated? Is it worth learning
properly, or can you just muddle through? Reading this thread has made me
all to aware that is exactly what I am doing.


So, what is it _"exactly"_ you're doing? Learning properly or muddling
through? I am just learning to read English, I guess. Or maybe muddling
through it. Depends on your point of view.
Jul 22 '05 #5

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:mU*****************@newsread1.dllstx09.us.to. verio.net...
John Harrison wrote:
[...]
Rob, you obviously have a thorough understanding of ADL (Koenig lookup I
still like to call it). How many other people do you find understand all
the subtleties? Do you think it is too complicated? Is it worth learning
properly, or can you just muddle through? Reading this thread has made me
all to aware that is exactly what I am doing.


So, what is it _"exactly"_ you're doing? Learning properly or muddling
through? I am just learning to read English, I guess. Or maybe muddling
through it. Depends on your point of view.


Some bits of C++ I've made an attempt to study and to learn thoroughly. Some
bits I've learned by trial and error. Koenig lookup is definitely in the
latter category. I'm wondering if I should actually spend some time studying
it, would that actually be useful? I'm not expecting Rob to answer that
question for me, just tell me about his experiences. That's all I'm trying
to say

john
Jul 22 '05 #6
John Harrison wrote in news:30*************@uni-berlin.de in
comp.lang.c++:

- namespace std, by ADL as ostream and pair are declared there.
- namespace std, as ostream_iterator is defined there [1]
- namespace :: (global) as it containes std [1].

However in both non-ADL cases [1] the namespace is only searched
for declaration's that existed *prior* to the defenition of
ostream_iterator.

Your declaration/defenition was added *after* that point so
it isn't found.
That's amazing. I changed the OP's example slightly. On Comeau C++
this compiles

#include <utility>
#include <iosfwd>

typedef std::pair<int, int> Pair;

std::ostream& operator<<(std::ostream& os, const Pair& v);


but this (which is just a rearrangement) doesn't

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

typedef std::pair<int, int> Pair;

std::ostream& operator<<(std::ostream& os, const Pair& v);
Which means I think that predict what code will compile in cases like
these you have to known precisely what definitions are included by
which header files.

And any header can include any other header and an implementation
doesen't have to document it, so its UB.

Note if you make one of std::map's arguments a UDT then ADL
will find your declaration.


Rob, you obviously have a thorough understanding of ADL (Koenig lookup
I still like to call it).


I suspect that many people simply avoid ADL 'cause thay think its
more complicated than it really is. Certainly when I first read
the term Koenig lookup thats what I thought.

Start calling it ADL (Argument Dependant Lookup) and spell it out
so other's get the benifit of this simple demystification too.
How many other people do you find understand
all the subtleties?
No idea (and I'm not sure I understand all the subtleties), but yes
there are plenty of people who don't get it, but remember there are
millions of C++ programmers out there that don't get half the things
we regulars of c.l.c++ consider basics. They still manage to write
effective programmes though.

All that aside the feature we're discussing here is actually to
do with how dependant name lookup interacts with ADL.

There are two ways that a programmer can provide a dependant name
after is is used, by specializing an existing declaration or by
ADL.

The rule about ADL can be abused, as your first example did, but
it isn't a language feature I'd try to exploit.
Do you think it is too complicated? Is it worth
learning properly, or can you just muddle through? Reading this thread
has made me all to aware that is exactly what I am doing.


Too compilacted for what ?, it certainly isn't too complicated to learn.

Or do you mean too compilcated a feature ? I'm kindof 50-50 on that.
I'd much rather it needed to be explicity enabled (except for operators
maybe).

Anyway you should learn it, but as to how you do that I don't know,
probably by using it, IOW use namespcaes, but you probably do that
anyway.

ADL mostly just works(tm), when it doesn't it is usualy because a
generic function (template) has been put in a namespace with types
declarations that it isn't supposed to work on:

#include <vector>
namespace eg
{
typedef std::vector< int > ivect_t;
void copy( ivect_t&, ivect_t&, ivect_t& );

void f()
{
ivect_t a, b, c;
copy( a, b, c ); /* may try to call std::copy */
(copy)(a, b, c); /* Ok eg::copy */
eg::copy( a, b, c ); /* ok */
}
}

Write such functions in a nested namespace and hoist them with a
using declaration/statment and the problem goes away. If it hurts
don't do it :). { if you can :-( }.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #7
Victor Bazarov wrote:
The problem is in "argument-dependent name lookup". The operator << is
not found in the global namespace (where you declared it) becuase both
its operands (ostream and pair) are declared in 'std' namespace. The
work-around for this is to place your operator << in 'std' namespace.
Ugly, but works:

namespace std {
ostream& operator <<(ostream& os, const Map::value_type& v);
}

V


Also illegal.

-Arijit
Jul 22 '05 #8
"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@130.133. 1.4...

ADL mostly just works(tm), when it doesn't it is usualy because a
generic function (template) has been put in a namespace with types
declarations that it isn't supposed to work on:

#include <vector>
namespace eg
{
typedef std::vector< int > ivect_t;
void copy( ivect_t&, ivect_t&, ivect_t& );

void f()
{
ivect_t a, b, c;
copy( a, b, c ); /* may try to call std::copy */
(copy)(a, b, c); /* Ok eg::copy */
eg::copy( a, b, c ); /* ok */
}
}

Write such functions in a nested namespace and hoist them with a
using declaration/statment and the problem goes away. If it hurts
don't do it :). { if you can :-( }.


Thank you for explanation. I think John is quite good at C++,
and when he says "complicated", it would be really complicated for me.
I've came across the term Koenig lookup several times, but haven't
study what it is, just thought "Is that named after Andrew Koenig?"
It seems this is the right time to learn it.

And would you explain again the relevant language rule (copy)(a, b, c)
calls eg::copy?

--
ES Kim
Jul 22 '05 #9
ES Kim wrote in news:cn**********@news1.kornet.net in comp.lang.c++:
And would you explain again the relevant language rule (copy)(a, b, c)
calls eg::copy?


3.4.2 Argument-dependent name lookup

When an unqualified name is used as the postfix-expression in a
function call (5.2.2), other namespaces not considered during
the usual unqualified lookup (3.4.1) ...

With emphasis:

unqualified name is used *as* the postfix-expression

In the case of (copy)(a, b, c) the postfix-expresion used in the
function call is "(copy)", for ADL to work it is *required* that
the postfix-expresion be an unqualified name i.e. "copy", so ADL
doesn't apply.

Hope I explained that sufficiently well.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: James Thurley | last post by:
I'm trying to dynamically compile assemblies and cache them to disk, which seems to work fine. When the data I'm compiling from changes, I want to re-generate the assembly and use the new version....
4
by: Fernando Cuenca | last post by:
Hi, I'm trying to explicitly instantiate a template function using the following syntax: obj.template_func<type>(params); It compiles OK when used from a regular function, but it doesn't...
12
by: Rhino | last post by:
I am having an odd problem: the sqlj command on my system doesn't work. I am running DB2 (LUW) V8 (FP8) on WinXP. I haven't done an sqlj program since Version 6 of DB2 (LUW) so I checked the...
3
by: Karl Irvin | last post by:
When I click Debug>Compile, my modules seem to comple OK but the Compile menu choice doesn't gray out (to indicate compiling is not needed). The IsCompiles returns false, no matter how many times...
149
by: Christopher Benson-Manica | last post by:
(Followups set to comp.std.c. Apologies if the crosspost is unwelcome.) strchr() is to strrchr() as strstr() is to strrstr(), but strrstr() isn't part of the standard. Why not? --...
1
by: rvan | last post by:
Hi, I am trying to port one of my older MFC APP created in VC 6.0 to VC 7.0. Right away after starting the compile process, I get following errors and compilation stops. "d:\Microsoft .NET...
4
by: Eric Lilja | last post by:
Is this an invalid program? Doesn't compile on my system: #include <cstdio> class Why { enum TArch {LITTLE_ENDIAN, BIG_ENDIAN, NON_IEEE}; TArch Architecture; }; int
10
by: Sourcerer | last post by:
I wrote this very simple code in .NET VC++. I compiled it on my system, and tried to run it on my friend's computer (he doesn't have the compiler). We both have Windows XP Professional. I have .NET...
13
by: hn.ft.pris | last post by:
Hi: I have the following simple program: #include<iostream> using namespace std; int main(int argc, char* argv){ const double L = 1.234; const int T = static_cast<const int>(L); int arr;
35
by: mwelsh1118 | last post by:
Why doesn't C# allow incremental compilation like Java? Specifically, in Java I can compile single .java files in isolation. The resulting individual .class files can be grouped into .jar files....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.