Topic: Argument-dependent lookup


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/03/24
Raw View
Martin von Loewis wrote:
>
> Gabriel Netterdag <gabriel.netterdag@quidsoft.se> writes:
>
> > With respect to all the numerous examples like the above,
> > explaining argument-dependent lookup, it feels like I'm
> > missing something.
>
> I think the intent of the text is as follows: Syntactically, the token
> sequence 'f(a)' could be either
>
>     postfix   expression ( expression   list-opt )
>
> or
>
>     simple   type   specifier ( expression   list-opt )
>
> according to 5.2/1, depending on whether 'f' is a type or not. Here,
> 3/6 applies:
>
> # Some names denote types, classes, enumerations, or templates. In
> # general, it is necessary to determine whether or not a name denotes
> # one of these entities before parsing the program that contains
> # it. The process that determines this is called name lookup (3.4).
>
> So when confronted with an identifier, all we have to determine is
> whether it is a type-name (e.g. a class-name or a typedef-name). If it
> is not a type-name, the identifier is an identifier, and, through
> unqualified-id -> id-expresssion -> primary-expression ->
> postfix-expression, parses as a postfix-expression. All that's
> necessary here is to determine whether the identifier is a type name
> or not. Since it is not, 3.4.2 applies, and finds the function in the
> name space.
>
> I'd agree that this could be phrased more clearly.

But what about the following:

namespace N1
{
  class f {};
}

namespace N2
{
  class X {};
  void f(X, N1::f);
}

N2::X a;
N1::f b;

int main()
{
  f(a,b); // call to N2::f, or error?
}

On the one hand, Koenig lookup should find both f, which would be
a name conflict. OTOH, if we already decided that f is not a type,
N1::f cannot be chosen (it's a type), and therefore N2::f should
be called.

Which is the correct resolution?

---
[ 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/25
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
> namespace N1 { class f {}; }
> namespace N2 { class X {}; void f(X, N1::f); }
> N2::X a;
> N1::f b;
> int main()
> {
>   f(a,b); // call to N2::f, or error?
> }
>
> On the one hand, Koenig lookup should find both f, which would be
> a name conflict. OTOH, if we already decided that f is not a type,
> N1::f cannot be chosen (it's a type), and therefore N2::f should
> be called.
>
> Which is the correct resolution?

Koenig lookup causes both namespaces to be searched. There is
nevertheless no conflict, because we are now in the domain of
overload resolution. Proceding to 13.3, we see that we are
looking for a set of candidate functions from which to choose
a winner. Non-functions which happen to have the same name do
not matter.

---
[ 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: Gabriel Netterdag <gabriel.netterdag@quidsoft.se>
Date: 2000/03/22
Raw View
Consider this example from 3.4.2p2:

namespace NS {
  class T { };
  void f(T);
}

NS::T parm;

int main() {
  f(parm);  // OK: calls NS::f
}

I don't find the Standard very supportive in describing
why this should be well-formed and call NS::f.

3.4.1p1
In all the cases listed in 3.4.1, the scopes are searched for
a declaration in the order listed in each of the respective cate-
gories;  name look up ends as soon as a declaration is found for the
name. If no declaration is found, the program is ill-formed.

3.4.1p3
The lookup for an unqualified name used as the postfix-expression of a
function call is described in 3.4.2.
[Note: for  purposes of determining (during parsing) whether an expression
is a postfix-expression for a function call, the usual name lookup rules apply.
The rules in 3.4.2 have no effect on the syntactic interpretation of an expression ...

3.4.2p1
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 look up (3.4.1) may be searched ...


So in the example above, in order to determine if f is "used as a
postfix-expression in a function call", we have to use the usual
name lookup to find out if f is an lvalue referring to a function
or if it's a pointer to function type. This lookup will fail to find any
declaration for f and according to 3.4.1p1 it is ill-formed and
argument-dependent lookup shouldn't be considered.

With respect to all the numerous examples like the above,
explaining argument-dependent lookup, it feels like I'm
missing something.

Regards
//Gabriel

---
[ 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/23
Raw View
Gabriel Netterdag <gabriel.netterdag@quidsoft.se> writes:

> With respect to all the numerous examples like the above,
> explaining argument-dependent lookup, it feels like I'm
> missing something.

I think the intent of the text is as follows: Syntactically, the token
sequence 'f(a)' could be either

    postfix   expression ( expression   list-opt )

or

    simple   type   specifier ( expression   list-opt )

according to 5.2/1, depending on whether 'f' is a type or not. Here,
3/6 applies:

# Some names denote types, classes, enumerations, or templates. In
# general, it is necessary to determine whether or not a name denotes
# one of these entities before parsing the program that contains
# it. The process that determines this is called name lookup (3.4).

So when confronted with an identifier, all we have to determine is
whether it is a type-name (e.g. a class-name or a typedef-name). If it
is not a type-name, the identifier is an identifier, and, through
unqualified-id -> id-expresssion -> primary-expression ->
postfix-expression, parses as a postfix-expression. All that's
necessary here is to determine whether the identifier is a type name
or not. Since it is not, 3.4.2 applies, and finds the function in the
name space.

I'd agree that this could be phrased more clearly.

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: Gabriel Netterdag <gabriel.netterdag@quidsoft.se>
Date: 1999/10/21
Raw View
wmm@fastdial.net wrote:
>
> This could be better described in the Standard, but the intent is
> as follows:
>
> 3.4p1 says you can only get an overload set (as opposed to a single
> unique result of the lookup) if the result of the lookup is the
> name of a function.  That means that if you do the ordinary lookup
> in 3.4.1 for the name in a postfix expression and find a type (so
> that you're doing a function-style cast, as shown in the example in
> 3.4.1p3) or find an object (a pointer to function or a class object
> that has an "operator()" member function), you're done; there's
> nothing more to do.  If, however, you find a function name, a set of
> function names, or nothing, you perform the argument-dependent lookup
> in 3.4.2.  It's only after you've completed the lookup in 3.4.2 that
> the 3.4.1p1 prohibition against an empty result kicks in.
>
Yes, I agree with this, and this is how I used to interpret all
this before starting to think a little bit more about what it say.
Now I'm not so sure that the text really mean this.

The thing I'm concerned about is the case where the usual unqualified
lookup doesn't find any declaration(s). 3.4.2p1 say "When an unqualified
name is used as the postfix-expression in a function call (5.2.2)...".
To me, this imply that there is no way to "trigger" arg. dep. lookup
for the empty set of usual unqualified lookup.

I also think that "postfix-expression in a function call" is perhaps
not the best words to use here to describe what the postfix-expression
really should be. For example, a pointer/reference to function, is a valid
"postfix-expression in a function call" but would certainly not meet
the intention.

> The wording could definitely be improved to make all this clearer,
> but this is how it's supposed to be interpreted.
>
I assume that by saying this, you mean that the text is already clear
what should happen but could be improved (for mortals like me:)?

Regards
//Gabriel
---
[ 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: wmm@fastdial.net
Date: 1999/10/18
Raw View
In article <3806C551.25E3AF86@quidsoft.se>,
  Gabriel Netterdag <gabriel.netterdag@quidsoft.se> wrote:
> Consider this example from 3.4.2p2:
>
> namespace NS {
>   class T { };
>   void f(T);
> }
>
> NS::T parm;
>
> int main() {
>   f(parm);  // OK: calls NS::f
> }
>
> I don't find the Standard very supportive in describing
> why this should be well-formed and call NS::f.
>
> 3.4.1p1
> In all the cases listed in 3.4.1, the scopes are searched for
> a declaration in the order listed in each of the respective cate-
> gories;  name look up ends as soon as a declaration is found for the
> name. If no declaration is found, the program is ill-formed.
>
> 3.4.1p3
> The lookup for an unqualified name used as the postfix-expression of a
> function call is described in 3.4.2.
> [Note: for  purposes of determining (during parsing) whether an
expression
> is a postfix-expression for a function call, the usual name lookup
rules apply.
> The rules in 3.4.2 have no effect on the syntactic interpretation of
an expression ...
>
> 3.4.2p1
> 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 look up (3.4.1) may be searched ...
>
> So in the example above, in order to determine if f is "used as a
> postfix-expression in a function call", we have to use the usual
> name lookup to find out if f is an lvalue referring to a function
> or if it's a pointer to function type. This lookup will fail to find
any
> declaration for f and according to 3.4.1p1 it is ill-formed and
> argument-dependent lookup shouldn't be considered.

This could be better described in the Standard, but the intent is
as follows:

3.4p1 says you can only get an overload set (as opposed to a single
unique result of the lookup) if the result of the lookup is the
name of a function.  That means that if you do the ordinary lookup
in 3.4.1 for the name in a postfix expression and find a type (so
that you're doing a function-style cast, as shown in the example in
3.4.1p3) or find an object (a pointer to function or a class object
that has an "operator()" member function), you're done; there's
nothing more to do.  If, however, you find a function name, a set of
function names, or nothing, you perform the argument-dependent lookup
in 3.4.2.  It's only after you've completed the lookup in 3.4.2 that
the 3.4.1p1 prohibition against an empty result kicks in.

The wording could definitely be improved to make all this clearer,
but this is how it's supposed to be interpreted.

--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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: Gabriel Netterdag <gabriel.netterdag@quidsoft.se>
Date: 1999/10/15
Raw View

[To moderators of comp.std.c++: I posted this article
two days ago and it hasn't appeared yet. Is it gone
or just in the queue? Anyway below is the
original article. Thanks, Gabriel]

Consider this example from 3.4.2p2:

namespace NS {
  class T { };
  void f(T);
}

NS::T parm;

int main() {
  f(parm);  // OK: calls NS::f
}

I don't find the Standard very supportive in describing
why this should be well-formed and call NS::f.

3.4.1p1
In all the cases listed in 3.4.1, the scopes are searched for
a declaration in the order listed in each of the respective cate-
gories;  name look up ends as soon as a declaration is found for the
name. If no declaration is found, the program is ill-formed.

3.4.1p3
The lookup for an unqualified name used as the postfix-expression of a
function call is described in 3.4.2.
[Note: for  purposes of determining (during parsing) whether an expression
is a postfix-expression for a function call, the usual name lookup rules apply.
The rules in 3.4.2 have no effect on the syntactic interpretation of an expression ...

3.4.2p1
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 look up (3.4.1) may be searched ...


So in the example above, in order to determine if f is "used as a
postfix-expression in a function call", we have to use the usual
name lookup to find out if f is an lvalue referring to a function
or if it's a pointer to function type. This lookup will fail to find any
declaration for f and according to 3.4.1p1 it is ill-formed and
argument-dependent lookup shouldn't be considered.

With respect to all the numerous examples like the above,
explaining argument-dependent lookup, it feels like I'm
missing something.

Regards
//Gabriel


[ 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              ]