I don't understand 3.4/2 in the Standard

I don't understand 3.4/2 in the Standard:

A name “looked up in the context of an expression” is looked up as an unqualified name in the scope where the expression is found.

What if the name is qualified, as N::i below?

#include <iostream>

namespace N { int i = 1; }

int main()
{
    int i = 0;

    std::cout << N::i << '\n';
}

The qualified name N::i is not looked up in the scope where N::i is found, i.e., it's not looked up in the scope of main() and the global scope!

Answers


To expand on the comment by @JerryCoffin, the rules for qualified lookup are:

3.4.3 Qualified name lookup [basic.lookup.qual]

3 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.

Here's an example:

#include <iostream>

struct N { enum { i = 1 }; };

int main()
{
    std::cout << N::i << '\n'; // prints 1

    struct N { enum { i = 0 }; };

    std::cout << N::i << '\n'; // prints 0
}

Live Example.


First the left-hand side of :: is looked up, and then the right-hand side is looked up inside it. So, to look up N::i, first it finds N using unqualified lookup, then it looks inside N to find i. Simple!

In your example, you redefine N locally. After the local definition, the outer definition is hidden per §3.3.10: "A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class."

Since the compiler knows at the outset that the left-hand side (N) must yield a type, namespace, or enumeration, any other lookup results (i.e. functions, variables, and templates) are ignored. So, you could also do:

#include <iostream>

struct N { enum { i = 1 }; };

int main()
{
    int N = 3;
    std::cout << N::i << '\n'; // prints 1
    std::cout << N << '\n'; // prints 3

    struct N { enum { i = 0 }; };

    std::cout << N::i << '\n'; // prints 0
}

http://coliru.stacked-crooked.com/a/9a7c9e34b1e74ce7

See §3.4.3/1:

The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.


Need Your Help

split firstname and lastname but only on first space

sql sql-server

I'm trying to split a string in MSSQL by only the first whitespace

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.