Topic: Koenig lookup questions


Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Fri, 13 Dec 2002 19:22:00 +0000 (UTC)
Raw View
Andy Sawyer wrote:
> > MingW/GCC 3.2 compiles it but Comeau 4.3.0.1 complains fill() unknown.
> >
> > #include <vector>
> > #include <algorithm>
> >
> > int main() {
> >    std::vector<int> vi(10);
> >    std::vector<int>::iterator k = vi.begin();
> >    fill(k, k + 10, 0);
> > }
> >
 The code above is yet another gotcha: don't assume that std::vector's
iterators are part of namespase std...

> Note that this isn't uniqe to vector and its iterators - in theory,
> any std container's iterators could be types defined elsewhere than
> std.
 IMHO it's nothing more than a STL design flaw (w.r.t. to ADL).
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 03:54:37 +0000 (UTC)
Raw View
===================================== MODERATOR'S COMMENT:
 This subthread is hereby declared DEAD.  :-)


===================================== END OF MODERATOR'S COMMENT
Andy Sawyer wrote:
> Of move to a country where participation does
 > not attract a membership fee.

The fees are to pay for the lavish food and exotic
dancers at the meetings. I just want the notes! :-)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 9 Dec 2002 07:21:23 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
> Interesting enough is the following:
>
>   Notes from the 10/01 meeting:
>
>   There was unanimous agreement on one less controversial point: if the
>   normal lookup of the identifier finds a non-function,
>   argument-dependent lookup should not be done.

Yay! Finally a straight answer to my question. Good.
That's exactly the resolution I was hoping for (and
I guess I'm not surprised that it was unanimous), but
I hadn't seen it clearly stated anywhere. I did notice
that this is how Comeau implements it.

By the way, are there legal reasons that notes from the
meetings can't be made available in their entirety, or is
it just a preference of the members? (That would be
understandable, since they might feel freer to say things
they know weren't going to be splattered all over the
internet, but the amount of detailed knowledge contained
in those notes must be enormous.)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: news@evo6.com (Andy Sawyer)
Date: Mon, 9 Dec 2002 09:38:09 +0000 (UTC)
Raw View
In article <6d73vu4tdbros6t3h94roqf4plsp65u7h1@4ax.com>,
 on Mon, 9 Dec 2002 00:30:59 +0000 (UTC),
 gp1@paradise.net.nz (Graeme Prentice) wrote:

> Since this is an ADL thread ...  should this code compile?

It's implementation defined.

> MingW/GCC 3.2 compiles it but Comeau 4.3.0.1 complains fill() unknown.
>
> #include <vector>
> #include <algorithm>
>
> int main() {
>    std::vector<int> vi(10);
>    std::vector<int>::iterator k = vi.begin();
>    fill(k, k + 10, 0);
> }
>
> 3.4.2 para 2 says "Typedef names and using declarations used to
> specify the types do not contribute to this set."
>
> Does this mean that *any* type that was created with a typedef doesn't
> "activate" ADL  -  including e.g. typedefs in traits classes.

ADL is based on the actual type, not typedef names. The type of
std::vector<int>::iterator is implementation defined, in some
implementations it's "int *", and "int *" isn't defined in namespace
std, so std isn't searched for fill in your example. If, on the other
hand, std::vector<int>::iterator is a type defined in std (as it is in
some cases), ADL will find std::fill. (There is - or at least was - at
least one library implementation for which the above would compile
sucessfully in "safe" mode, but not in "release" mode).

Note that this isn't uniqe to vector and its iterators - in theory,
any std container's iterators could be types defined elsewhere than
std. (In practice, however, they rarely are which - in practice -
makes std::vector's iterators the "odd ones out")

Regards,
 Andy S.
--
"Light thinks it travels faster than anything but it is wrong. No matter
 how fast light travels it finds the darkness has always got there first,
 and is waiting for it."                  -- Terry Pratchett, Reaper Man

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gp1@paradise.net.nz (Graeme Prentice)
Date: Mon, 9 Dec 2002 18:12:24 +0000 (UTC)
Raw View
On Mon, 9 Dec 2002 09:38:09 +0000 (UTC), news@evo6.com (Andy Sawyer)
wrote:

>
>ADL is based on the actual type, not typedef names. The type of
>std::vector<int>::iterator is implementation defined, in some
>implementations it's "int *", and "int *" isn't defined in namespace
>std, so std isn't searched for fill in your example. If, on the other
>hand, std::vector<int>::iterator is a type defined in std (as it is in
>some cases), ADL will find std::fill. (There is - or at least was - at
>least one library implementation for which the above would compile
>sucessfully in "safe" mode, but not in "release" mode).
>
>Note that this isn't uniqe to vector and its iterators - in theory,
>any std container's iterators could be types defined elsewhere than
>std. (In practice, however, they rarely are which - in practice -
>makes std::vector's iterators the "odd ones out")
>

Thanks.  From looking through the MinGW GCC 3.2 header files, I've
discovered that vector<>::iterator is actually a template class  -
class __normal_iterator<>
containing a whole bunch of overloaded operators.  So GCC is correct
in compiling the code I posted.  Makes me wonder what Dinkumware does.

The advice I've often seen about not assuming that vector iterator is
an int* is worth listening to.  If the compiler does inlining properly
there shouldn't be any loss of efficiency either.

Graeme

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Mon, 9 Dec 2002 18:13:29 +0000 (UTC)
Raw View
Hyman Rosen wrote:
....
> By the way, are there legal reasons that notes from the
> meetings can't be made available in their entirety, or is
> it just a preference of the members? (That would be
> understandable, since they might feel freer to say things
> they know weren't going to be splattered all over the
> internet, but the amount of detailed knowledge contained
> in those notes must be enormous.)

Being able to read those notes is one of the perks of membership; I
imagine they might want to encourage anyone who's that curious to pay a
membership fee.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 5 Dec 2002 23:50:50 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
 > I can't find any support for that in the Standard.

I'd say he's describing the idea behind ADL,
not the exact details.

Oh, and by the way, there is also 3.4/1 to consider,

     Name lookup shall find an unambiguous declaration
     for the name (see 10.2). Name lookup may associate
     more than one declaration for a name if it finds
     the name to be a function name;

So if ADL is applied to the pointer-to-function case,
and the associated namespaces have a function whose
name matches the pointer, the program is illegal?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Sat, 7 Dec 2002 22:30:25 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) writes:

| Gabriel Dos Reis wrote:
|  > I can't find any support for that in the Standard.
|
| I'd say he's describing the idea behind ADL,
| not the exact details.
|
| Oh, and by the way, there is also 3.4/1 to consider,
|
|      Name lookup shall find an unambiguous declaration
|      for the name (see 10.2). Name lookup may associate
|      more than one declaration for a name if it finds
|      the name to be a function name;
|
| So if ADL is applied to the pointer-to-function case,
| and the associated namespaces have a function whose
| name matches the pointer, the program is illegal?

Some people consider that to be a reason why ADL should ignore
non-function names.  Some people think that since name-lookup are
designed to apply uniformly, then the above is a reason to make the
program ill-formed if name-lookup in the associated namespaces
(which uses ordinary rules) finds a non-function name.

Interesting enough is the following:

  Notes from the 10/01 meeting:

  There was unanimous agreement on one less controversial point: if the
  normal lookup of the identifier finds a non-function,
  argument-dependent lookup should not be done.

--
Gabriel Dos Reis,       gdr@intgerable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gp1@paradise.net.nz (Graeme Prentice)
Date: Mon, 9 Dec 2002 00:30:59 +0000 (UTC)
Raw View
Since this is an ADL thread ...  should this code compile?
MingW/GCC 3.2 compiles it but Comeau 4.3.0.1 complains fill() unknown.

#include <vector>
#include <algorithm>

int main() {
   std::vector<int> vi(10);
   std::vector<int>::iterator k = vi.begin();
   fill(k, k + 10, 0);
}

3.4.2 para 2 says "Typedef names and using declarations used to
specify the types do not contribute to this set."

Does this mean that *any* type that was created with a typedef doesn't
"activate" ADL  -  including e.g. typedefs in traits classes.

Graeme

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: news@evo6.com (Andy Sawyer)
Date: Mon, 9 Dec 2002 23:29:41 +0000 (UTC)
Raw View
In article <lnu8vukihr466kk5c6j037puki82ia18q8@4ax.com>,
 on Mon, 9 Dec 2002 18:12:24 +0000 (UTC),
 gp1@paradise.net.nz (Graeme Prentice) wrote:

> On Mon, 9 Dec 2002 09:38:09 +0000 (UTC), news@evo6.com (Andy Sawyer)
> wrote:
>
> >ADL is based on the actual type, not typedef names. The type of
> >std::vector<int>::iterator is implementation defined, in some
> >implementations it's "int *", and "int *" isn't defined in namespace
> >std, so std isn't searched for fill in your example. If, on the other
> >hand, std::vector<int>::iterator is a type defined in std (as it is in
> >some cases), ADL will find std::fill. (There is - or at least was - at
> >least one library implementation for which the above would compile
> >sucessfully in "safe" mode, but not in "release" mode).
> >
> >Note that this isn't uniqe to vector and its iterators - in theory,
> >any std container's iterators could be types defined elsewhere than
> >std. (In practice, however, they rarely are which - in practice -
> >makes std::vector's iterators the "odd ones out")
> >
>
> Thanks.

No worries.

> From looking through the MinGW GCC 3.2 header files, I've discovered
> that vector<>::iterator is actually a template class - class
> __normal_iterator<> containing a whole bunch of overloaded
> operators.

Which is reasonable.

> So GCC is correct in compiling the code I posted.

Only if __normal_iterator is defined in namespace std. I guess it must
be.

> Makes me wonder what Dinkumware does.

Last time I looked, it does the perfectly reasonable (and fairly
common) thing, and uses "T *" as std::vector<T>::iterator.

> The advice I've often seen about not assuming that vector iterator
> is an int* is worth listening to.

It certainly is. Further, you shouldn't assume that
std::container::iterator is a type defined in namespace std
(specifically, words, you can't assume that ADL will find algortihms
from std just because one of the arguments is an iterator).

> If the compiler does inlining properly there shouldn't be any loss
> of efficiency either.

inlining and certain other possible optimisations, yes.

Regards,
 Andy S.
--
"Light thinks it travels faster than anything but it is wrong. No matter
 how fast light travels it finds the darkness has always got there first,
 and is waiting for it."                  -- Terry Pratchett, Reaper Man

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: news@evo6.com (Andy Sawyer)
Date: Mon, 9 Dec 2002 23:43:34 +0000 (UTC)
Raw View
In article <3DF4AB6C.80506@wizard.net>,
 on Mon, 9 Dec 2002 18:13:29 +0000 (UTC),
 kuyper@wizard.net ("James Kuyper Jr.") wrote:

> Hyman Rosen wrote:
> ....
> > By the way, are there legal reasons that notes from the
> > meetings can't be made available in their entirety, or is
> > it just a preference of the members? (That would be
> > understandable, since they might feel freer to say things
> > they know weren't going to be splattered all over the
> > internet, but the amount of detailed knowledge contained
> > in those notes must be enormous.)
>
> Being able to read those notes is one of the perks of membership; I
> imagine they might want to encourage anyone who's that curious to pay
> a membership fee.

Of move to a country where participation does not attract a membership
fee.

Regards,
 Andy S.
--
"Light thinks it travels faster than anything but it is wrong. No matter
 how fast light travels it finds the darkness has always got there first,
 and is waiting for it."                  -- Terry Pratchett, Reaper Man

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 9 Dec 2002 23:45:59 +0000 (UTC)
Raw View
news@evo6.com (Andy Sawyer) writes:

[...]

| > So GCC is correct in compiling the code I posted.
|
| Only if __normal_iterator is defined in namespace std. I guess it must
| be.

No, it isn't.  Still GCC is right in accepting the code.

The class template __normal_iterator<> is defined in the GNU
implementation/extension namespace __gnu_cxx::.

GCC is correct because std::vector<T>::iterator is actually a synonymous
for __normal_iterator<T*, std::vector<T> > and Koenig lookup considers
also the namespaces associated to template arguments, which in this
case include std::.

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mortys76388@aol.com ("Morty")
Date: Wed, 4 Dec 2002 19:31:24 +0000 (UTC)
Raw View
"Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
news:m365uauork.fsf@uniton.integrable-solutions.net...
> I guess I shall repeat that all these are active issues under
> consideration in the Core Working Group.  I guess I shall repeat that
> you might want to read the tip at
>
>    http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#218
>
> of a looooong discussion on the Core Working Group reflector.

Thanks, that's just what I was looking for.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 4 Dec 2002 20:07:06 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
 > If the left-hand operand of () is a name, it
> should be looked up using koenig lookup.

My major concern remains with what is done when the
ordinary lookup finds a non-function. My sense is that
ADL is intended to add to the overload set of functions
to consider, and therefore should not apply when the
ordinary lookup finds a non-function. It is incredibly
counter-intuitive for an ADL-found function to be
preferred over an in-scope function pointer with the
same name. It means that you must never use the plain
pf(x) syntax for calling through a function pointer
because you never know when the name of the function
pointer will be hijacked by an associated namespace.
I just find that unacceptable.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Wed, 4 Dec 2002 21:25:47 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) writes:

| Gabriel Dos Reis wrote:
|  > If the left-hand operand of () is a name, it
| > should be looked up using koenig lookup.

The above actually was written by Bjarne Stroustrup -- you can check
out following the link I gave in my message --; I just happen to agree
with it.

| My major concern remains with what is done when the
| ordinary lookup finds a non-function. My sense is that
| ADL is intended to add to the overload set of functions
| to consider, and therefore should not apply when the
| ordinary lookup finds a non-function.

Except that, that is not what is written (which presumably is why you
submitted the DR).  The discussion that followed your submission
revealed that there is no unanimous agreement that what you think
was what was intended.

| It is incredibly
| counter-intuitive for an ADL-found function to be
| preferred over an in-scope function pointer with the
| same name. It means that you must never use the plain
| pf(x) syntax for calling through a function pointer

"You should be explicit about type issues", that was essentially what
I was told when I, a long time ago, asked the question:

   why isn't there is any comparable decay applied in
   "object.pfm(args)" which would "simplify"  (object.*pfm)(args).

| because you never know when the name of the function
| pointer will be hijacked by an associated namespace.

Well, I think that argument can be made nearly everywhere ADL is used
-- possibly excepting the operators case.

I agree that there is a problem about the "proper" way programs should
be written; but I'm not yet convinced about what the "right" solution
should be.

| I just find that unacceptable.

Note that in classic C, one already had to write "(*pf)(args)"; I don't
whether that was found "unacceptable".

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 5 Dec 2002 00:39:27 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
> | > If the left-hand operand of () is a name, it
> | > should be looked up using koenig lookup.
>
> The above actually was written by Bjarne Stroustrup -- you can check
> out following the link I gave in my message --; I just happen to agree
> with it.

In _The C++ Programming Language_ section 8.2.6 he writes

     Consequently, if a function isn't found in the
     context of its use, we look in the namespaces
     of its arguments.

which very much supports my view of things. Of course
the Devil may quote scripture for his purpose :-)

> Except that, that is not what is written (which presumably is why you
> submitted the DR).  The discussion that followed your submission
> revealed that there is no unanimous agreement that what you think
> was what was intended.

I submitted the DR because I think the wording is unclear at best.
The discussion given in the DR veers off into whether ADL can find
non-functions, mostly failing to address my question of what happens
when ordinary lookup finds a non-function.

I find support for my case in 5.2.2/1, which says

     If a function or member function name is used,
     the name can be overloaded

I would argue that if ordinary lookup finds a non-function,
then the above does not apply, no overloading is possible,
and the non-function simply gets used.

> Note that in classic C, one already had to write "(*pf)(args)";

But not in Standard C, where the pf(args) notation was blessed.
In fact, I believe that Standard C defines function call only
in terms of pointer to function, with f(args) being defined by
allowing the usual decay from function name.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 5 Dec 2002 06:28:10 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) writes:

| Gabriel Dos Reis wrote:
| > | > If the left-hand operand of () is a name, it
| > | > should be looked up using koenig lookup.
| > The above actually was written by Bjarne Stroustrup -- you can check
| > out following the link I gave in my message --; I just happen to agree
| > with it.
|
| In _The C++ Programming Language_ section 8.2.6 he writes
|
|      Consequently, if a function isn't found in the
|      context of its use, we look in the namespaces
|      of its arguments.
|
| which very much supports my view of things. Of course
| the Devil may quote scripture for his purpose :-)

The above seems to imply that the following

     #include <iostream>

     namespace N
     {
         struct A { /* ... */ };
         void f(A)
         { std::cout << "N::f" << std::endl; }
     }

     void f(N::A)
     { std::cout << "::f" << std::endl; }

     int main()
     {
       using ::f;
       N::A a;
       f(a);
     }

is well-formed and should output '::f'.  I can't find any support for
that in the Standard.

| > Except that, that is not what is written (which presumably is why you
| > submitted the DR).  The discussion that followed your submission
| > revealed that there is no unanimous agreement that what you think
| > was what was intended.
|
| I submitted the DR because I think the wording is unclear at best.
| The discussion given in the DR veers off into whether ADL can find
| non-functions, mostly failing to address my question of what happens
| when ordinary lookup finds a non-function.

The discussion was much more elaborate than what you can see on the
public website. The issue of what ADL finds naturally came up as part
of addressing your question.  But I agree that most energy was put in
that matter.

| I find support for my case in 5.2.2/1, which says
|
|      If a function or member function name is used,
|      the name can be overloaded

I find that a bit confused because overloading happens only in a
*given scope* whereas ADL transgresses scope boundaries.  Therefore,
I think it would take some elaborated reasoning to apply it to ADL.

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mortys76388@aol.com ("Morty")
Date: Sun, 1 Dec 2002 18:14:34 +0000 (UTC)
Raw View
"Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
news:m3hee267tq.fsf@uniton.integrable-solutions.net...
> It is still an active core issue whether Koenig lookup does find
> non-function names; different people have different opinions on the
> matter.

What I found googling on the topic is:

1) The illustrative examples are all minor variations on the trivial case in
the Standard, and hence are unhelpful.

2) The one article that hints at it is one on MSDN where it implies that
only function names are found.

> Personnaly, I think lookup should proceed uniformly.

Koenig lookup is already way outside the uniform way lookup is done anyway,
and is loaded with its own special cases like no typedefs, no using names,
friend name injection, etc.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gp1@paradise.net.nz (Graeme Prentice)
Date: Sun, 1 Dec 2002 18:20:52 +0000 (UTC)
Raw View
On Wed, 27 Nov 2002 23:08:17 +0000 (UTC), hyrosen@mail.com (Hyman
Rosen) wrote:

>Gabriel Dos Reis wrote:
>> Personnaly, I think lookup should proceed uniformly.
>
>For what it's worth, Comeau finds the parameter, not the ADL
>function. The following compiles. Reversing one and two makes
>it fail. This is the result I want and expect, but I would
>like to see quoted chapter and verse which makes it so. It also
>works if I declare 'two (*f)(...);' in global scope instead of
>as a parameter. But if I declare 'two f(...);' in global scope
>then it fails, preferring N::f.

You can't overload pointers to functions  e.g. the following is
illegal in the same scope
void (*f)(int);
void (*f)(float);

so in spirit, argument dependent lookup should not occur when it finds
f is a pointer in the local scope  -  but the precise wording of the
standard is that ADL occurs when  - quote 3.4.2   "When an unqualified
name is used as the postfixexpression"   -  and doesn't distinguish
between function pointers and function names.

GCC 3.2 agrees with Comeau and doesn't do the ADL when it finds the
local function pointer.

There's also a defect report that says if it finds the function name
at local block scope then ADL doesn't occur.

Graeme

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 2 Dec 2002 07:02:18 +0000 (UTC)
Raw View
gp1@paradise.net.nz (Graeme Prentice) writes:

| so in spirit, argument dependent lookup should not occur when it finds
| f is a pointer in the local scope  -  but the precise wording of the
| standard is that ADL occurs when  - quote 3.4.2   "When an unqualified
| name is used as the postfixexpression"   -  and doesn't distinguish
| between function pointers and function names.

Morepver, the wording standard doesn't say exactly when Koenig lookup
is performed; I mean in the presence of the function-call syntax, is
Koenig lookup done "in parallel" with or after ordinary lookup?

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 2 Dec 2002 07:02:19 +0000 (UTC)
Raw View
mortys76388@aol.com ("Morty") writes:

| "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
| news:m3hee267tq.fsf@uniton.integrable-solutions.net...
| > It is still an active core issue whether Koenig lookup does find
| > non-function names; different people have different opinions on the
| > matter.
|
| What I found googling on the topic is:
|
| 1) The illustrative examples are all minor variations on the trivial case in
| the Standard, and hence are unhelpful.
|
| 2) The one article that hints at it is one on MSDN where it implies that
| only function names are found.

Ahem, I think Dave Abraham has posted several examples on the topic
and I'm having trouble in qualifying them as "minor variations on the
trivial case in the Standard".

| > Personnaly, I think lookup should proceed uniformly.
|
| Koenig lookup is already way outside the uniform way lookup is done anyway,

"uniformly" in my sentence stood for "unformly to all names"
i.e. makes no distinction between function names, type names or
variable names.  The issue is whether the wordings in the Standard
make it so explicitl, apart from

3.4/1
  The name lookup rules apply uniformly to all names (including
  typedef-names (7.1.3), namespace-names (7.3) and class-names (9.1))
  wherever the grammar allows such names in the context discussed by a
  partic-ular rule. [...]

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Mon, 2 Dec 2002 16:34:35 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
....
> Morepver, the wording standard doesn't say exactly when Koenig lookup
> is performed; I mean in the presence of the function-call syntax, is
> Koenig lookup done "in parallel" with or after ordinary lookup?

The rules for Koenig lookup change "If the ordinary unqualified lookup
of the find finds the declaration of a class member function ...".
Therefore, ordinary unqualified lookup has to occur first; at least
enough of it has to occur to determine that particular issue. Otherwise,
it simply doesn't matter which kind of lookup occurs first.

The main effect of Koenig lookup is to simply add to the list of
possible declarations matching a given name; that list is not ordered
according to whether the name was found by normal or Koenig lookup. If a
name becomes ambiguous as a result of Koenig lookup, then the program is
ill-formed, except when overloading applies. When overloading does
apply, section 13.3 resolves the ambiguity, and none of the rules in
13.3 distinguishes the two kinds of lookup (except for one case,
13.3.1.1.2p1).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 2 Dec 2002 18:35:21 +0000 (UTC)
Raw View
kuyper@wizard.net ("James Kuyper Jr.") writes:

| Gabriel Dos Reis wrote:
| ....
| > Morepver, the wording standard doesn't say exactly when Koenig lookup
| > is performed; I mean in the presence of the function-call syntax, is
| > Koenig lookup done "in parallel" with or after ordinary lookup?
|
| The rules for Koenig lookup change "If the ordinary unqualified lookup
| of the find finds the declaration of a class member function
| ...". Therefore, ordinary unqualified lookup has to occur first;

No, that doesn't follow.

Firstly, what you quote is exactly what is in C++98.  What changes are
you talking about.

Secondly, there is nothing in the above quote that implies that Koenig
lookup happens after ordinary lookup.  Indeed, the above doesn't
outlaw a parallel name-lookup, ordinary lookup and Koenig lookup
running in parallel each tagging the declaration it found.
The paragraph you started quoting continues with:

   Otherwise the set of declarations found by the lookup of the
   function name is the union of the set of declarations found using
   ordinary unqualified lookup and the set of declarations found in
   the namespaces and classes associated with the argument types.

Again, this wording doesn't not outlaw a parallel lookup.

--
Gabriel Dos Reis,       gdr@inetgable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mortys76388@aol.com ("Morty")
Date: Mon, 2 Dec 2002 21:00:37 +0000 (UTC)
Raw View
"Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
news:m3wumtv7n8.fsf@uniton.integrable-solutions.net...
> Ahem, I think Dave Abraham has posted several examples on the topic
> and I'm having trouble in qualifying them as "minor variations on the
> trivial case in the Standard".

Perhaps I missed them. Do you have a url handy? Do any of them address the
examples in the post initiating this thread?

> "uniformly" in my sentence stood for "unformly to all names"
> i.e. makes no distinction between function names, type names or
> variable names.

Ok, my mistake.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dag.henriksson@quidsoft.se ("Dag Henriksson")
Date: Mon, 2 Dec 2002 22:59:07 +0000 (UTC)
Raw View
"Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
news:m31y50e4c5.fsf@uniton.integrable-solutions.net...
> kuyper@wizard.net ("James Kuyper Jr.") writes:
>
> | Gabriel Dos Reis wrote:
> | ....
> | > Morepver, the wording standard doesn't say exactly when Koenig
lookup
> | > is performed; I mean in the presence of the function-call syntax,
is
> | > Koenig lookup done "in parallel" with or after ordinary lookup?

Doesn't an ordinary lookup has to be done in order to determine if a
Koenig lookup should be done at all? Before we have done the ordinary
lookup we dont know if the name is used as "the postfix-expression of a
function call", or if the name is a type (doing a function-style cast).

--
Dag Henriksson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 2 Dec 2002 23:52:06 +0000 (UTC)
Raw View
dag.henriksson@quidsoft.se ("Dag Henriksson") writes:

| "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
| news:m31y50e4c5.fsf@uniton.integrable-solutions.net...
| > kuyper@wizard.net ("James Kuyper Jr.") writes:
| >
| > | Gabriel Dos Reis wrote:
| > | ....
| > | > Morepver, the wording standard doesn't say exactly when Koenig
| lookup
| > | > is performed; I mean in the presence of the function-call syntax,
| is
| > | > Koenig lookup done "in parallel" with or after ordinary lookup?
|
| Doesn't an ordinary lookup has to be done in order to determine if a
| Koenig lookup should be done at all?

The ordinary lookup disambiguates between postfix-expression and
explicit type conversion, but does that necessarily mean that Koenig
lookup is not done in parallel?

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Tue, 3 Dec 2002 14:20:53 +0000 (UTC)
Raw View
mortys76388@aol.com ("Morty") writes:

| "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
| news:m3wumtv7n8.fsf@uniton.integrable-solutions.net...
| > Ahem, I think Dave Abraham has posted several examples on the topic
| > and I'm having trouble in qualifying them as "minor variations on the
| > trivial case in the Standard".
|
| Perhaps I missed them. Do you have a url handy?

One being:

  http://gcc.gnu.org/ml/gcc-prs/2002-06/msg00532.html

where a non-function is found.

| Do any of them address the
| examples in the post initiating this thread?

Sorry, I don't understand what you mean here.

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Tue, 3 Dec 2002 14:21:05 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
> kuyper@wizard.net ("James Kuyper Jr.") writes:
....
> | The rules for Koenig lookup change "If the ordinary unqualified lookup
> | of the find finds the declaration of a class member function
> | ...". Therefore, ordinary unqualified lookup has to occur first;
>
> No, that doesn't follow.
>
> Firstly, what you quote is exactly what is in C++98.  What changes are
> you talking about.

I'm talking about the change in algorithm between the "If" clause and
the following "Otherwise" clause, not the change from one version of C++
to another. Because that "If" depends upon the results of an unqualified
lookup, unqualified lookup conceptually occurs before Koenig lookup.

> Secondly, there is nothing in the above quote that implies that Koenig
> lookup happens after ordinary lookup.  Indeed, the above doesn't
> outlaw a parallel name-lookup, ordinary lookup and Koenig lookup
> running in parallel each tagging the declaration it found.

Conceptually, that clause requires the following process:

overload_list = ordinary_lookup();
overload_list.append(koenig_lookup(overload_list));

You can probably come up with a clever algorithm that does the two
lookups in parallel. You could have one step do a lenient version of
Koenig lookup that ignores the "If", then have another step do ordinary
lookup, and then if the ordinary lookup found a class member function,
you would remove anything found exclusively through the lenient Koenig
lookup. However, proper Koenig lookup can't be considered to be complete
until that has been done.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mortys76388@aol.com ("Morty")
Date: Tue, 3 Dec 2002 18:10:57 +0000 (UTC)
Raw View
"Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
news:m3wumsf0hc.fsf@uniton.integrable-solutions.net...
> mortys76388@aol.com ("Morty") writes:
> | "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
> | news:m3wumtv7n8.fsf@uniton.integrable-solutions.net...
> | > Ahem, I think Dave Abraham has posted several examples on the topic
> | > and I'm having trouble in qualifying them as "minor variations on the
> | > trivial case in the Standard".
> | Perhaps I missed them. Do you have a url handy?
> One being:
>   http://gcc.gnu.org/ml/gcc-prs/2002-06/msg00532.html
> where a non-function is found.

Thanks, it's a function template found, not really a non-function.

> | Do any of them address the
> | examples in the post initiating this thread?
> Sorry, I don't understand what you mean here.

I shall repeat the examples:
------------------------------------------
The description in the standard 3.4.2 is a little thin on what happens when
the names are not functions. For example, what happens with the following:

namespace NS {
    class T { }
    class X { X(T) { } }
}
NS::T parm;
int main() {
    X(parm);    // NS::X is a class, not a function
}

==============================

namespace NS {
    class T { }
    void X(T);
}
class X { X(T) { } }
NS::T parm;
int main() {
    X(parm);    // does NS::X override class ::X ?
}

===============================

namespace NS {
    class T { }
    int X;
}
void X(T) { }
NS::T parm;
int main() {
    X(parm);    // is this an ambiguity error?
}



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Wed, 4 Dec 2002 15:23:01 +0000 (UTC)
Raw View
mortys76388@aol.com ("Morty") writes:

| "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
| news:m3wumsf0hc.fsf@uniton.integrable-solutions.net...
| > mortys76388@aol.com ("Morty") writes:
| > | "Gabriel Dos Reis" <gdr@integrable-solutions.net> wrote in message
| > | news:m3wumtv7n8.fsf@uniton.integrable-solutions.net...
| > | > Ahem, I think Dave Abraham has posted several examples on the topic
| > | > and I'm having trouble in qualifying them as "minor variations on the
| > | > trivial case in the Standard".
| > | Perhaps I missed them. Do you have a url handy?
| > One being:
| >   http://gcc.gnu.org/ml/gcc-prs/2002-06/msg00532.html
| > where a non-function is found.
|
| Thanks, it's a function template found, not really a non-function.

  1) A *type* name was being found.

  2) something is either a function or not a function.  There is
     no such thing as "not really a non-function".

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Wed, 4 Dec 2002 16:52:33 +0000 (UTC)
Raw View
mortys76388@aol.com ("Morty") writes:

[...]

| I shall repeat the examples:
| ------------------------------------------
| The description in the standard 3.4.2 is a little thin on what happens when
| the names are not functions. For example, what happens with the following:
|
| namespace NS {
|     class T { }
|     class X { X(T) { } }
| }
| NS::T parm;
| int main() {
|     X(parm);    // NS::X is a class, not a function
| }
|
| ==============================
|
| namespace NS {
|     class T { }
|     void X(T);
| }
| class X { X(T) { } }
| NS::T parm;
| int main() {
|     X(parm);    // does NS::X override class ::X ?
| }
|
| ===============================
|
| namespace NS {
|     class T { }
|     int X;
| }
| void X(T) { }
| NS::T parm;
| int main() {
|     X(parm);    // is this an ambiguity error?
| }

I guess I shall repeat that all these are active issues under
consideration in the Core Working Group.  I guess I shall repeat that
you might want to read the tip at

   http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#218

of a looooong discussion on the Core Working Group reflector.

I guess I shall repeat that I share the opinion expressed in

   I don't think we could seriously argue from first principles that
   [argument-dependent lookup should find only function declarations].
   In general, C++ name lookup is designed to be independent of type:
   First we find the name(s), then, we consider its(their)
   meaning. 3.4  basic.lookup states "The name lookup rules
   apply uniformly to all names ..." That is an important principle.

   Thus, I consider text that speaks of "function call" instead of plain
   "call" or "application of ()" in the context of koenig lookup an
   accident of history. I find it hard to understand how 5.2.2  expr.call
   doesn't either disallow all occurrences of x(y) where x is a class
   object (that's clearly not intended) or requires koenig lookup for x
   independently of its type (by reference from 3.4  basic.lookup). I
   suspect that a clarification of 5.2.2  expr.call to mention function
   objects is in order. If the left-hand operand of () is a name, it
   should be looked up using koenig lookup.

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: mortys76388@aol.com ("Morty")
Date: Wed, 27 Nov 2002 01:11:02 +0000 (UTC)
Raw View
The description in the standard 3.4.2 is a little thin on what happens when
the names are not functions. For example, what happens with the following:

namespace NS {
    class T { }
    class X { X(T) { } }
}
NS::T parm;
int main() {
    X(parm);    // NS::X is a class, not a function
}

==============================

namespace NS {
    class T { }
    void X(T);
}
class X { X(T) { } }
NS::T parm;
int main() {
    X(parm);    // does NS::X override class ::X ?
}

===============================

namespace NS {
    class T { }
    int X;
}
void X(T) { }
NS::T parm;
int main() {
    X(parm);    // is this an ambiguity error?
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 27 Nov 2002 17:49:36 +0000 (UTC)
Raw View
Morty wrote:
> The description in the standard 3.4.2 is a little thin on what happens when
> the names are not functions.

This is the one I always wonder about -

namespace NS
{
     class T
     {
          operator int() const;
     };
     void f(T)
     {
     }
}

void g(void (*f)(...), NS::T t)
{
     f(t); // parameter f, or NS::f ?
}

template <typename T>
void h(void (*f)(...), T t)
{
     f(t); //when T is NS::T, parameter f, or NS::f ?
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Wed, 27 Nov 2002 18:14:14 +0000 (UTC)
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote...
> Morty wrote:
> > The description in the standard 3.4.2 is a little thin on what happens
when
> > the names are not functions.
>
> This is the one I always wonder about -
>
> namespace NS
> {
>      class T
>      {
>           operator int() const;
>      };
>      void f(T)
>      {
>      }
> }
>
> void g(void (*f)(...), NS::T t)
> {
>      f(t); // parameter f, or NS::f ?

Parameter.  Name hiding is in effect, IMHO.  Of course, I am
not very good at interpreting the Standard...

> }
>
> template <typename T>
> void h(void (*f)(...), T t)
> {
>      f(t); //when T is NS::T, parameter f, or NS::f ?

Again, if name hiding is in effect, then it shouldn't matter,
should it?

> }

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 27 Nov 2002 19:45:27 +0000 (UTC)
Raw View
Victor Bazarov wrote:
> Parameter.  Name hiding is in effect, IMHO.  Of course, I am
> not very good at interpreting the Standard...

What does name hiding have to do with it?
ADL's purpose is to find names that aren't visible!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Wed, 27 Nov 2002 20:20:01 +0000 (UTC)
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote...
> Victor Bazarov wrote:
> > Parameter.  Name hiding is in effect, IMHO.  Of course, I am
> > not very good at interpreting the Standard...
>
> What does name hiding have to do with it?

Probably nothing.  Since 'f' is not visible in the function scope
by itself (without argument lookup), the parameter 'f' (the pointer
to a function) declaration simply introduces that name in the body
of the function.  Let's consider it a slip of the typing finger...

> ADL's purpose is to find names that aren't visible!

Well, in addition to those that are already visible, like the
parameters in your case.  So, 'NS::f' is found along with 'f' (the
parameter), and since the parameter has ellipsis for its parameter
list, the 'NS::f' should be prefered during the overloaded name
resolution (see clause 13).  So, I take my statement back and now
assert that the 'NS::f' should be used.

How about that?

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 27 Nov 2002 21:06:19 +0000 (UTC)
Raw View
Victor Bazarov wrote:
 > So, I take my statement back and now
> assert that the 'NS::f' should be used.
>
> How about that?

That's what I'm afraid of. How many people, when calling
through what they think is a pointer to function, would
expect that a different function could be called? Does
this mean that when you have a pointer to function, you
should always call it using (f)(args) instead of f(args)?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Wed, 27 Nov 2002 21:39:01 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) writes:

| Victor Bazarov wrote:
|  > So, I take my statement back and now
| > assert that the 'NS::f' should be used.
| > How about that?
|
| That's what I'm afraid of. How many people, when calling
| through what they think is a pointer to function, would

It is still an active core issue whether Koenig lookup does find
non-function names; different people have different opinions on the
matter.

Personnaly, I think lookup should proceed uniformly.

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 27 Nov 2002 23:08:17 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
> Personnaly, I think lookup should proceed uniformly.

For what it's worth, Comeau finds the parameter, not the ADL
function. The following compiles. Reversing one and two makes
it fail. This is the result I want and expect, but I would
like to see quoted chapter and verse which makes it so. It also
works if I declare 'two (*f)(...);' in global scope instead of
as a parameter. But if I declare 'two f(...);' in global scope
then it fails, preferring N::f.

typedef char (&one)[1];
typedef char (&two)[2];

namespace N
{
     struct T
     {
         operator int() const;
     };
     one f(T);
}

void g(two (*f)(...), N::T t)
{
     extern char a[sizeof(f(t)) - 1];
}

template<typename T>
void h(two (*f)(...), T t)
{
     extern char a[sizeof(f(t)) - 1];
}
template void h<>(two (*)(...), N::T);

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 28 Nov 2002 03:08:19 +0000 (UTC)
Raw View
Gabriel Dos Reis wrote:
> It is still an active core issue whether Koenig lookup does find
> non-function names; different people have different opinions on the
> matter.

Notice that we are talking about the opposite problem here.
We have a non-function name which would be overridden by ADL
finding a function name.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Sandra Loosemore <sandra@shore.net>
Date: 2000/03/28
Raw View
I am finding the discussion of Koenig lookup in the standard (sections
3.4.2 and 13.3.1.1) very confusing and open to multiple interpretations.
Can someone who understands what the real intent is supposed to be help
clarify what is supposed to happen in cases where there are non-function
declarations of the name being used as the postfix-expression?

Assume I have a call of the form f(x,y) where x and y are values of
class types X and Y, respectively.

What happens if some of the scopes that are searched for declarations
of f declare it as a function, but others declare it to be a
non-function?  Is this an error, or are non-function declarations
ignored?

What happens if a non-function declaration of f appears at block
scope?  Specifically....

What happens if there is a block-scope declaration of f as an
appropriate function pointer visible?

What happens if there is a block-scope declaration of f as an object
of class type visible?  Should operator() and surrogate call functions
from f's class be considered for overloading resolution instead of, or
in addition to, declarations of f from X's and Y's namespaces?

If the answer to the previous two cases is that the block-scope
declaration of f shadows any declarations that might be found through
argument-dependent lookup, is this also what happens if the block-scope
declaration of f is a function declaration?  Or are declarations of f
from X's and Y's namespaces considered for overload resolution
in addition to the local declaration of f in that case?

Are the answers to these questions any different if we are talking
about an operator called through regular operator syntax instead of
through an explicit funciton call?

-Sandra the confused

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 2000/03/28
Raw View
Sandra Loosemore <sandra@shore.net> writes:
> Assume I have a call of the form f(x,y) where x and y are values of
> class types X and Y, respectively.
>
> What happens if some of the scopes that are searched for declarations
> of f declare it as a function, but others declare it to be a
> non-function?  Is this an error, or are non-function declarations
> ignored?

Non-functions are ignored, because overloading looks for candidate
functions. See 13.3.1.1.1/3.

> What happens if there is a block-scope declaration of f as an
> appropriate function pointer visible?

That f is called.

> What happens if there is a block-scope declaration of f as an object
> of class type visible?  Should operator() and surrogate call functions
> from f's class be considered for overloading resolution instead of, or
> in addition to, declarations of f from X's and Y's namespaces?

Only the calls from f's class are considered. Koenig lookup is not used.

> If the answer to the previous two cases is that the block-scope
> declaration of f shadows any declarations that might be found through
> argument-dependent lookup, is this also what happens if the block-scope
> declaration of f is a function declaration?  Or are declarations of f
> from X's and Y's namespaces considered for overload resolution
> in addition to the local declaration of f in that case?

This is where Koenig lookup is used. The candidates from the
other namespaces are involved in overload resolution along with
the block-scope f.

> Are the answers to these questions any different if we are talking
> about an operator called through regular operator syntax instead of
> through an explicit funciton call?

You mean f.operator()(x, y) ? No Koenig lookup is involved in this
case, and the normal lookup of f must find an object. If you mean
f(x,y) and normal lookup finds an object named f, then no Koenig
lookup happens here either. See 13.3.1.1.2.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 2000/03/29
Raw View
Hyman Rosen <hymie@prolifics.com> writes:

> Non-functions are ignored, because overloading looks for candidate
> functions. See 13.3.1.1.1/3.

I cannot find a sentence in 13.3.1.1.1/3 saying that objects or types
are ignored. What sentence are you referring to?

I'd say that it is ill-formed if lookup finds an object. 3.4.2/3 says
that that essentially qualified lookup is performed for the associated
namespaces. I'd assume that 7.3.4/4 most closely resembles the
situation in Koenig lookup:

# If name lookup finds a declaration for a name in two different
# namespaces, and the declarations do not declare the same entity and
# do not declare functions, the use of the name is ill   formed.

A note then specifically points out that class-names in other
namespaces are *not* hidden, so it would be even an error if Koenig
lookup finds a class in one of the associated namespaces.

> > What happens if there is a block-scope declaration of f as an
> > appropriate function pointer visible?
>
> That f is called.

Why is that? It still is is a postfix-expression, so 3.4.2 still
applies. 3.4.2/2 makes an exception if ordinary lookup finds a member
declaration; it does not make an exception if it finds a block-scope
declaration. IOW,

namespace Foo{
  void bar();
  struct C{};
  void func(C&);
}
using Foo::C;

int main(){
  void (*bar)(C&) = Foo::func;
  C c;
  bar(c);
}

is ill-formed: normal lookup finds an object, Koenig lookup finds a
function, i.e. not all declarations are functions.

> > What happens if there is a block-scope declaration of f as an object
> > of class type visible?  Should operator() and surrogate call functions
> > from f's class be considered for overloading resolution instead of, or
> > in addition to, declarations of f from X's and Y's namespaces?
>
> Only the calls from f's class are considered. Koenig lookup is not used.

Sure is. It still is an "unqualified name [...] used as the
postfix   expression in a function call", so Koenig lookup applies.

Using the above statement, I'd say the call is ill-formed if Koenig
lookup actually finds functions in other namespaces, on the basis of
7.3.4/4.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Sandra Loosemore <sandra@shore.net>
Date: 2000/03/30
Raw View
Hyman Rosen <hymie@prolifics.com> writes:

> Sandra Loosemore <sandra@shore.net> writes:
> > Assume I have a call of the form f(x,y) where x and y are values of
> > class types X and Y, respectively.
> >
> > What happens if some of the scopes that are searched for declarations
> > of f declare it as a function, but others declare it to be a
> > non-function?  Is this an error, or are non-function declarations
> > ignored?
>
> Non-functions are ignored, because overloading looks for candidate
> functions. See 13.3.1.1.1/3.

This paragraph says section 3.4.2 applies to lookup of the name that
appears in the function call syntax, not to selection of candidate
functions for overloading resolution.  Similarly the discussion in
section 3.4.2 is all about name lookup and says nothing about
overloading.  And neither 13.3.1.1.1 nor 3.4.2 address the case of
what is supposed to happen when the name doesn't resolve to a function.

> > What happens if there is a block-scope declaration of f as an
> > appropriate function pointer visible?
>
> That f is called.

Where in the standard is this stated?  It doesn't seem to distinguish
this case at all from the call to a function denoted by a name which
is discussed in 13.3.1.1.1.  The standard seems to say that when the
postfix-expression *syntactically* has the form given 13.3.1.1.1, the
name lookup rules in 3.4.2 apply.

> > What happens if there is a block-scope declaration of f as an object
> > of class type visible?  Should operator() and surrogate call functions
> > from f's class be considered for overloading resolution instead of, or
> > in addition to, declarations of f from X's and Y's namespaces?
>
> Only the calls from f's class are considered. Koenig lookup is not used.

Where in the standard is this stated?  Again, 13.3.1.1.1 seems to
address all function call expressions where the function expression is
syntactically denoted by a name, and while 13.3.1.1.2 discusses calls
to an object of class type, I can't find anything that says which takes
precedence when the function expression has the syntax of a name *and*
also has class type.

> > If the answer to the previous two cases is that the block-scope
> > declaration of f shadows any declarations that might be found through
> > argument-dependent lookup, is this also what happens if the block-scope
> > declaration of f is a function declaration?  Or are declarations of f
> > from X's and Y's namespaces considered for overload resolution
> > in addition to the local declaration of f in that case?
>
> This is where Koenig lookup is used. The candidates from the
> other namespaces are involved in overload resolution along with
> the block-scope f.

If this is different than the other cases, it seems like some kind of
circular logic is required -- the compiler has to look up the name in a
function call expression before it can determine which way to look up
the name.

> > Are the answers to these questions any different if we are talking
> > about an operator called through regular operator syntax instead of
> > through an explicit funciton call?
>
> You mean f.operator()(x, y) ? No Koenig lookup is involved in this
> case, and the normal lookup of f must find an object. If you mean
> f(x,y) and normal lookup finds an object named f, then no Koenig
> lookup happens here either. See 13.3.1.1.2.

No, I'm talking about calls to an overloaded operator -- say an
expression like (x + y), where instead of f we have operator+.

-Sandra the still-confused

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Biju Thomas <b.thomas@attglobal.net>
Date: 2000/03/30
Raw View
Martin von Loewis wrote:
>
> 3.4.2/2 makes an exception if ordinary lookup finds a member
> declaration; it does not make an exception if it finds a block-scope
> declaration. IOW,
>
> namespace Foo{
>   void bar();
>   struct C{};
>   void func(C&);
> }
> using Foo::C;
>
> int main(){
>   void (*bar)(C&) = Foo::func;
>   C c;
>   bar(c);
> }
>
> is ill-formed: normal lookup finds an object, Koenig lookup finds a
> function, i.e. not all declarations are functions.
>

I don't think the above code is ill-formed. Here, namespace scope is
considered  only after the block-scope within the 'main' function is
considered. Since a declaration is found there, the compiler won't go
further to look in the namespace scope. (If in fact it went to look in
the namespace scope, Koenig lookup would have been applied.)

--
Biju Thomas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 2000/03/30
Raw View
Sandra Loosemore <sandra@shore.net> writes:
> If this is different than the other cases, it seems like some kind of
> circular logic is required -- the compiler has to look up the name in a
> function call expression before it can determine which way to look up
> the name.

It may be that there is a defect in the Standard. I would say that the
compiler should first do a normal lookup on the name in a function call.
If the normal lookup finds only a set of 0 or more functions, then that
set should be augmented via Koenig lookup. Otherwise, you can get weird
situations like having the following code fail to work as expected.

namespace N
{
 struct B { };
 void functor(int, B) { }
 void actor(int, B) { }
}

void apply0(void (*functor)(N::B), N::B argument)
{
 functor(0, argument);
}

void f()
{
 apply0(N::actor, B());
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]