Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between declaring a name, introducing a name, and declaring an entity

From the C++11 standard, §7.3.3[namespace.udecl]/1:

A using-declaration introduces a name into the declarative region in which the using-declaration appears.

using-declaration:

using typenameoptnested-name-specifier unqualified-id ;
using :: unqualified-id ;

The member name specified in a using-declaration is declared in the declarative region in which the using-declaration appears.

What do they mean by the name being declared in the declarative region where the using-declaration occurs?

Does this mean the same as introducing that name into the declarative region where the using-declaration occurs?

Also is there a difference between declaring a name and declaring the entity that the name denotes?

Example:

namespace N { static int i = 1; } /* Declares an entity denoted by 
    the name i in the declarative region of the namespace N. 
    Introduces the name into the declarative region of the namespace N.
    Declares the name i in the declarative region of the namespace N? */
using N::i; /* Declares the name i in the declarative region of the
    global namespace. Also introduces that name into the declarative
    region of the global namespace? Also declares the entity that the
    name i denotes? */ 
like image 762
Supremum Avatar asked Jul 29 '15 18:07

Supremum


1 Answers

From first principles, an entity is, from [basic]

a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, parameter pack, or this. [...] Every name that denotes an entity is introduced by a declaration.

Declarations declare things. To be declared means that it was introduced by a declaration, from [basic.scope.declarative]

Every name is introduced in some portion of program text called a declarative region, which is the largest part of the program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the same entity.

The names declared by a declaration are introduced into the scope in which the declaration occurs, except that the presence of a friend specifier (11.3), certain uses of the elaborated-type-specifier (7.1.6.3), and using-directives (7.3.4) alter this general behavior.

None of those exceptions are relevant here, since we're talking about using-declarations and not using-directives. Let me alter your example somewhat so as to avoid the global namespace:

namespace N {        //  + declarative region #1
                     //  |
    static int i;    //  | introduces a name into this region
                     //  | this declaration introduces an entity
}                    //  +

So to start with, N::i is an entity that is declared in namespace N and introduced into the scope of N. Now, let's add a using-declaration:

namespace B {        //  + declarative region #2
                     //  |
    using N::i;      //  | declaration introduces a name i
                     //  | but this is not an entity
}                    //  +

From [namespace.udecl], we have:

If a using-declaration names a constructor (3.4.3.1), it implicitly declares a set of constructors in the class in which the using-declaration appears (12.9); otherwise the name specified in a using-declaration is a synonym for a set of declarations in another namespace or class.

The using-declaration using N::i does not name a constructor, so rather than having the name i be a new entity, it is instead a synonym for N::i.

So basically, both is are names introduced in and declared in their respective namespaces. In N, i declares an entity with static linkage, but in B, i declares a synonym to that entity - not a new entity.

like image 192
Barry Avatar answered Sep 20 '22 05:09

Barry