user2953119
user2953119

Reputation:

Why does unqualified name lookup find all overloaded declarations

Here is an example which I'm trying to understand how does unqualified name look up work for overloaded declarations:

int foo(char a){ return 0; }

namespace A
{
    int foo(int a){ return a; }
    int foo(){ return 2; }
    extern int j;
    extern int i;
}

int A::j=foo('a'); //97
int A::i=foo(); //2

It means that int foo(char); does not found by unqualified name look up but int foo(int); and int foo() can be found. So I assume that unqualified name look up for overloaded declaration ends as soon as all overloaded declarations is found for the name. I can't find this into the standard, I can find only the following (sec. 3.4.1):

name look up ends as soon as a declaration is found for the name.

This quote doesn't say anything about overloaded declaration look up.

Upvotes: 1

Views: 114

Answers (4)

R Sahu
R Sahu

Reputation: 206607

You said

It means that int foo(char); does not found by unqualified name look up but int foo(int); and int foo() can be found. So I assume that unqualified name look up for overloaded declaration ends as soon as all overloaded declarations is found for the name.

A similar question was asked in another SO post

There is from 3.4.1/14:

If a variable member of a namespace is defined outside of the scope of its namespace then any name that appears in the definition of the member (after the declarator-id) is looked up as if the definition of the member occurred in its namespace.

Your posted code is equivalent to:

int foo(char a){ return 0; }

namespace A
{
    int foo(int a){ return a; }
    int foo(){ return 2; }
    extern int j;
    extern int i;
}

namespace A
{
  int j=foo('a');
  int i=foo();
}

When the definitions and initializations are put under the namespace, it becomes clear why functions used to initialize the variables are looked up in namespace A first. If an unambiguous match can be found for a function in namespace A, the search for it stops. That means, when compiling the line,

int A::j=foo('a');

The lookup for foo starts in namespace A, is resolved to int A::foo(int); and the search for foo stops.

Hope this clears the confusion.

Upvotes: 0

M.M
M.M

Reputation: 141586

You're mixing up name lookup with overload resolution. There is no such thing as "unqualified name look up for overloaded declaration". Name lookup and overload resolution are separate.

Name lookup means determining which scope the name is found in. Once that is completed, overload resolution determines which of the declarations visible in that scope should be used.

In your code, name lookup determines that foo means A::foo. Then overload resolution selects between A::foo() and A::foo(int). The ::foo is not considered for overload resolution because it is not a definition of A::foo.

Another example:

namespace C { void f(); }
namespace B { void f(); void f(float); }
namespace C { void f(long); }

using namespace C;

int main()
{
    f(1.0);
}

When processing the line f(1.0), name lookup sees void f(); and stops. The result is that f means C::f.

Then overload resolution kicks in, and all declarations of C::f are considered for overload resolution. void f(long) is chosen.

Upvotes: 3

Brian Bi
Brian Bi

Reputation: 119184

In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member’s class or namespace.

(C++11 §3.4.3/3)

So in both of

int A::j=foo('a');
int A::i=foo();

the name foo is looked up in the scope of A just because you have A::j and A::i to the left, in the declarator.

Note that if you do

int k = foo();

only the global foo will be found, and you'll get an error.

Upvotes: 1

Rakib
Rakib

Reputation: 7625

In the standard (§3.4/1)

Name lookup shall find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (Clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded.

Which means the steps are as follows for methods:

  1. First collect all the matching names
  2. Do overload resolution
  3. Check for accessibility

For method, name lookup does not return after finding first match, rather it searches for all matching names. It is clear from the statement Name lookup may associate more than one declaration with a name if it finds the name to be a function name.

Upvotes: -1

Related Questions