The difference between declaring a name, entering a name, and declaring an object

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

Use-declarations introduces the name into the declarative region in which the declaration of use appears.

using declaration:

using typename opt nested-name-specifier unqualified-id ;
using :: unqualified-id ;

The member name specified in the using declaration is declared in the declarative area in which the usage declaration appears.

What do they mean under the declaration declared in the declarative area where the use declaration is used?

Does this mean the same as entering this name in the declarative region where the usage declaration is found?

Is there also a difference between declaring a name and declaring an object indicated by that name?

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? */ 
+7
c ++ language-lawyer declaration entity using-declaration
source share
2 answers

From the first principles the essence, starting with [basic]

value, object, reference, function, enumerator, type, class member, bit field, pattern, specialization pattern, namespace, parameter package or this . [...] Each name denoting an object is entered by a declaration.

Ads announce things. To be declared means that it was introduced by a declaration from [basic.scope.declarative]

Each name is entered in some part of the program text, called the declarative region, which is the largest part of the program in which this name is valid, that is, in which this name can be used as an unqualified name to refer to the same object.

Names declared by the declaration are entered in the area in which the announcement occurs, except that the presence of the friend specifier (11.3), certain uses of the developed type specifier (7.1.6.3) and (7.3.4) change this general behavior.

None of these exceptions matter here, since we are talking about using-declarations, not about using-directives. Let me modify your example a bit to avoid a global namespace:

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

So, for starters, N::i is an entity declared in the namespace N and entered into the realm N Now add use-declarations:

 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 the using declaration calls the constructor (3.4.3.1), it implicitly declares the set of constructors in the class in which the usage declaration appears (12.9); otherwise, the name specified in the usage declaration is a synonym for a set of declarations in a different namespace or class.

Using a declaration using N::i does not name the constructor, so instead of having the name i be a new entity, instead it is a synonym for N::i .

Basically, both i are names entered and declared in their respective namespaces. In N , i declares an object with a static link, but in B , i declares a synonym for this entity - not a new object.

+6
source share

What do they mean by declaration in the declarative region where the declaration of use is used?

I will try to answer this with an example of my understanding of this (see my comments on the code shown):

 // "namespace X {}" introduces a declarative region of the namespace X namespace X { //The name SomeObject is now introduced into the declarative region X // It is only visible in that declarative region using Y::SomeObject; }//Declarative region X ENDS here // SomeObject NOT visible here 

The following is an example where the error (compiler) makes it clear where the name is not displayed:

 #include <iostream> namespace A { struct X{}; } namespace B { struct X{}; } namespace C { using A::X; void foo(X){} } namespace D { using B::X; void foo(X){} } void foo(X){} //FAILS TO COMPILE - DELIBERATE!!! int main() { return 0; } 
0
source share

All Articles