473,564 Members | 2,768 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why koenig lookup?

The so-called koenig lookup allows doing odd things like this:

#include <algorithm>
#include <string>

int main()
{
std::string table[10];
sort(table, table+10);
}

(Notice how the 'sort' doesn't have the std:: prefix, yet it's
perfectly valid.)

I understand that the reason for the koenig lookup to exist is so that
you can write things like:

std::cout << 5;

This is actually equivalent to:

operator<<(std: :cout, 5);

The koenig lookup allows the compiler to look for operator<< inside
the std namespace because one of the parameters is from that namespace.

With operators it makes sense. However, why perform the same lookup
for *all* functions? What's the advantage? Couldn't it be simply defined
that the koenig lookup is performed for operators but not for regular
functions?
Aug 9 '08 #1
16 1640
Juha Nieminen wrote:
The so-called koenig lookup allows doing odd things like this:

#include <algorithm>
#include <string>

int main()
{
std::string table[10];
sort(table, table+10);
}

(Notice how the 'sort' doesn't have the std:: prefix, yet it's
perfectly valid.)

I understand that the reason for the koenig lookup to exist is so that
you can write things like:

std::cout << 5;

This is actually equivalent to:

operator<<(std: :cout, 5);

The koenig lookup allows the compiler to look for operator<< inside
the std namespace because one of the parameters is from that namespace.

With operators it makes sense. However, why perform the same lookup
for *all* functions? What's the advantage? Couldn't it be simply defined
that the koenig lookup is performed for operators but not for regular
functions?
Well it saves a lot of typing, i think that's why it's working for
functions, too. If the function is valid in the namespace std, why
should you type it all the time. If you don't want to use std just don't
type "using namespace std;" at the beginning of your code. The compiler
will demand std:: all the time then.

If you type the line the compiler doesn't need the std:: anymore,
because you are already in the namespace std.
Aug 9 '08 #2
Captain Trips wrote:
Well it saves a lot of typing, i think that's why it's working for
functions, too. If the function is valid in the namespace std, why
should you type it all the time. If you don't want to use std just don't
type "using namespace std;" at the beginning of your code. The compiler
will demand std:: all the time then.

If you type the line the compiler doesn't need the std:: anymore,
because you are already in the namespace std.
Uh? I think you are talking about a completely different issue. I was
not talking about "using" at all.
Aug 9 '08 #3
In article <g7**********@s agnix.uni-muenster.de>, Captain Trips
<us*******@un i-muenster.dewrot e:
[Koenig lookup]

Well it saves a lot of typing, i think that's why it's working for
functions, too. If the function is valid in the namespace std, why
should you type it all the time. If you don't want to use std just don't
type "using namespace std;" at the beginning of your code. The compiler
will demand std:: all the time then.
That was his point; it does NOT need std:: here, even though there is no
"sort" in the scope of main, and no using directive bringing namespace std
into scope. Simply because table, one of the arguments to the function
call, was of a type whose definition was in namespace std, the sort
function was chosen.
Aug 9 '08 #4
On Aug 9, 5:08 pm, Juha Nieminen <nos...@thanks. invalidwrote:
The so-called koenig lookup allows doing odd things like this:
#include <algorithm>
#include <string>
int main()
{
std::string table[10];
sort(table, table+10);
}
(Notice how the 'sort' doesn't have the std:: prefix, yet it's
perfectly valid.)
I understand that the reason for the koenig lookup to exist is
so that you can write things like:
std::cout << 5;
This is actually equivalent to:
operator<<(std: :cout, 5);
The koenig lookup allows the compiler to look for operator<<
inside the std namespace because one of the parameters is from
that namespace.
With operators it makes sense. However, why perform the same
lookup for *all* functions? What's the advantage? Couldn't it
be simply defined that the koenig lookup is performed for
operators but not for regular functions?
What's the difference between a function and an operator, except
the invocation syntax? Orthogonality, if nothing else, requires
that the same lookup applies. In addition:

#include <BigDecimal.h h>

int
main()
{
using SomeNamespace:: BigDecimal ;
BigDecimal z1 ;
BigDecimal z2 = sin( z1 ) ;
// Do you really think it reasonable to have to write
// SomeNamespace:: sin here?
}

And of course, in a template, you don't really even have the
choice.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #5
On Aug 9, 7:46 pm, "Alf P. Steinbach" <al...@start.no wrote:
* Juha Nieminen:
The so-called koenig lookup allows doing odd things like
this:
#include <algorithm>
#include <string>
int main()
{
std::string table[10];
sort(table, table+10);
}
(Notice how the 'sort' doesn't have the std:: prefix, yet
it's perfectly valid.)
I understand that the reason for the koenig lookup to exist
is so that you can write things like:
std::cout << 5;
This is actually equivalent to:
operator<<(std: :cout, 5);
The koenig lookup allows the compiler to look for operator<<
inside the std namespace because one of the parameters is
from that namespace.
With operators it makes sense. However, why perform the same
lookup for *all* functions? What's the advantage? Couldn't
it be simply defined that the koenig lookup is performed for
operators but not for regular functions?

I don't think Andrew Koenig, or /anyone else/, fully grokked
the consequences at the time.
Well, he certainly didn't have any concrete experience with it
before it was standardized. However...
If ADL (argument-dependent lookup) was defined today, now that
we've had some experience with it, then I'm pretty sure it
would be restricted to operators, and perhaps -- but just
perhaps -- extended in another direction, namely for lookup
of arguments in classes, where it's a hassle to have to
qualify things all the time, as opposed to the case
exemplified above, where it just introduces problems and
complexity without conferring any advantage.
A few experimental implementations had been made with namespace,
and I think it was concrete experience with them that led to the
understanding that something had to be done with functions. All
functions, not just overloaded operators. Now, given the time
frame, I personally think that the "correct" solution would have
been to back out of the problem completely, and drop namespaces
from that version of the standard, because of a lack of
knowledge with regards to the real problems that it might
introduce. (And in honesty, I have to admit that my fears were
largely unfounded.)

Off hand, I think if there were anything to do differently
(given namespaces and the way they work), it would be to have
the built in types imply the global namespace, rather than no
namespace.
I guess that goes to show that the job of standardization is
not to innovate. ;-)
I think at least some members of the committee share your
opinion there---at least part of the motivation behind Boost was
to provide a place where innovation would be appropriate, which
could be standardized once concrete experience was established.
(Regretfully, it only applies to libraries.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #6
On Aug 10, 3:19 pm, "Alf P. Steinbach" <al...@start.no wrote:
* James Kanze:
[...]
In addition:
#include <BigDecimal.h h>
int
main()
{
using SomeNamespace:: BigDecimal ;
BigDecimal z1 ;
BigDecimal z2 = sin( z1 ) ;
// Do you really think it reasonable to have to write
// SomeNamespace:: sin here?
}
I think this is a good point, that an overload of 'sin' should
not be introduced in a new namespace, but in the original
namespace, namely here the global one.
It doesn't work, because...
And of course, in a template, you don't really even have the
choice.
?
In a template, sin will be a dependent name, and will not be
looked up in the global namespace, only in the namespace where
BigDecimal was defined.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #7
On Aug 10, 6:45 pm, "Alf P. Steinbach" <al...@start.no wrote:
* James Kanze:
>And of course, in a template, you don't really even have the
choice.
?
In a template, sin will be a dependent name, and will not be
looked up in the global namespace, only in the namespace where
BigDecimal was defined.
If that was true then it would just reinforce the point that
ADL for named routines has turned out to be too problematic,
too many limiting corner cases.
I don't think the problem here is ADL. The problem is two phase
lookup in general.
However,
<code>
#include <iostream>
namespace james
{
struct BigInt {};
}
double sin( james::BigInt ) { return 0; }
template< typename T >
void foo()
{
sin( james::BigInt() );
}
is good standard C++.
But doesn't use sin in a dependent context in a dependent
context in the template. I was thinking of the classical case,
where the operator<< for std::vector<int defined in global
namespace doesn't get found when it is used in
std::ostream_it erator. Curiously, I can't reproduce the
symptomes in a simple example, but I've definitely had the
problem myself, and people post it here from time to time.

I did say dependent, didn't I, in my first posting. Now, either
two phase lookup is too complicated for even a guru like
yourself to catch onto the subtilities, or you're being
intentionally obtuse. (And regretfully, there's nothing ironic
about that. IMHO, two phase lookup does have enough subtilities
that even an expert can easily overlook them.)
So what you literally write, is incorrect, and argument void.
But still there is a good chance that you had some specific
scenario in mind, that I don't at present grok. And I'm
interested in that, on its own, so please, elaborate. :-)
See above. And the fact that even someone with your level
didn't catch on immediately just confirms my feeling that two
phase lookup, at least in its present form, was a mistake,
because it's just too complicated.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #8
In article <2a0f00c3-10cd-4b64-8203-57c5e681b565
@k13g2000hse.go oglegroups.com> , ja*********@gma il.com says...

[ ... ]
But doesn't use sin in a dependent context in a dependent
context in the template. I was thinking of the classical case,
where the operator<< for std::vector<int defined in global
namespace doesn't get found when it is used in
std::ostream_it erator. Curiously, I can't reproduce the
symptomes in a simple example, but I've definitely had the
problem myself, and people post it here from time to time.
Here's a fairly simple example:

#include <map>
#include <string>
#include <iostream>
#include <algorithm>

typedef std::map<std::s tring, ints_int;

//namespace std {

std::ostream &operator<<(std ::ostream &os, s_int::value_ty pe const &v)
{
return os << v.first << ": " << v.second;
}

//}

int main() {
s_int m;

m["a"] = 123;
m["b"] = 345;

std::copy(m.beg in(), m.end(),
std::ostream_it erator<s_int::v alue_type>(std: :cout, "\n"));

return 0;
}

As it stands right now, it won't compile -- but remove the two comment
delimiters so operator<< is in namespace std, and it compiles and works
just fine.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 10 '08 #9
Jerry Coffin wrote:
In article <2a0f00c3-10cd-4b64-8203-57c5e681b565
@k13g2000hse.go oglegroups.com> , ja*********@gma il.com says...

[ ... ]
>But doesn't use sin in a dependent context in a dependent
context in the template. I was thinking of the classical case,
where the operator<< for std::vector<int defined in global
namespace doesn't get found when it is used in
std::ostream_i terator. Curiously, I can't reproduce the
symptomes in a simple example, but I've definitely had the
problem myself, and people post it here from time to time.

Here's a fairly simple example:

#include <map>
#include <string>
#include <iostream>
#include <algorithm>

typedef std::map<std::s tring, ints_int;

//namespace std {

std::ostream &operator<<(std ::ostream &os, s_int::value_ty pe const &v)
{
return os << v.first << ": " << v.second;
}

//}

int main() {
s_int m;

m["a"] = 123;
m["b"] = 345;

std::copy(m.beg in(), m.end(),
std::ostream_it erator<s_int::v alue_type>(std: :cout, "\n"));

return 0;
}

As it stands right now, it won't compile -- but remove the two comment
delimiters so operator<< is in namespace std, and it compiles and works
just fine.
Lemme guess. operator<<(std: :ostream&, int ) is ***NOT*** in global
namespace Right? .. Which is the whole point!

I'm with Alf Steinbach on this one....

regards
Andy Little
Aug 11 '08 #10

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

Similar topics

1
1603
by: Dave | last post by:
#include <iostream> using std::cout; using std::endl; // #define CAUSE_ERROR namespace N { struct foo_t {};
11
1688
by: REH | last post by:
I'm a little confused about argument dependent lookup. Exactly when does this apply? Specifically, I was hoping to use it to access enumeration constants. For example: namespace Flags { enum flag_type {F1, F2, F3}; } void foo(Flags::flag_type f) {
2
1918
by: Jean-Louis Leroy | last post by:
I'm trying to compile the following code with gcc (version below). I would expect the compile to try the operator ==() declared in Tangram::Backend because of Koenig lookup. But it doesn't happen. Is it me or the compiler? namespace Tangram { namespace Backend { struct RELATIONAL;
3
2910
by: my-wings | last post by:
I've been reading about how evil Lookup fields in tables are, but I've got to be missing something really basic. I know this subject has been covered before, because I've just spent an hour or two reading about it on google, but there is something I still don't understand, and I'm hoping someone will be willing to explain it to me in small...
3
10618
by: google | last post by:
I have a database with four table. In one of the tables, I use about five lookup fields to get populate their dropdown list. I have read that lookup fields are really bad and may cause problems that are hard to find. The main problem I am having right now is that I have a report that is sorted by one of these lookup fields and it only displays...
3
1216
by: REH | last post by:
I'm a little confused about argument dependent lookup. Exactly when does this apply? Specifically, I was hoping to use it to access enumeration constants. For example: namespace Flags { enum flag_type {F1, F2, F3}; } void foo(Flags::flag_type f) {
5
2337
by: Javier Estrada | last post by:
I'm using a user-defined diagnostics stream and custom manipulators that work with it template<class charT, class traits = std::char_traits<charT> class basic_diagsstream : public std::basic_ostream<charT, traits ... } and a manipulator
2
2034
by: cgv | last post by:
Hi, I want to distinguish between an int parameter to a template function depending on whether its value is known at compile time or not. For the compile time version I want to call the function with the syntax func<5>(); and for the dynamic version with
2
2114
by: Peng Yu | last post by:
Hi, I'm wondering if Koenig lookup can be applied somehow to derive which template to use based on the template arguments. The following code shows an example where multiply_traits's namespace A has to be specified in the definition of Y. This makes Y unusable for any multiply_traits defined in other namespaces, which corresponding T1...
0
7665
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7583
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7888
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7642
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7950
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5213
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3643
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2082
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
924
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.