声明名称,引入名称和声明实体之间的区别

时间:2015-07-29 18:46:13

标签: c++ entity declaration language-lawyer using-declaration

来自C ++ 11标准,§7.3.3[namespace.udecl] / 1:

  

using声明在声明区域中引入了一个名称,其中出现了using声明。

     
    

using声明

         
      

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

    
  
     

在using声明中指定的成员名称在using声明出现的声明区域中声明。

在使用声明发生的声明性区域中声明的名称是什么意思?

这是否意味着将该名称引入发生using声明的声明性区域?

声明名称和声明名称所代表的实体之间是否有区别?

示例:

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? */ 

2 个答案:

答案 0 :(得分:6)

从第一原则来看,实体来自[basic]

  

值,对象,引用,函数,枚举器,类型,类成员,位字段,模板,模板   专业化,命名空间,参数包或this。 [...]表示实体的每个名称都由声明引入。

声明声明事物。待声明意味着它是由声明引入的,来自[basic.scope.declarative]

  

每个名称都引入程序文本的某些部分,称为声明区域,这是最大的部分   该名称有效的程序,即该名称可用作非限定名称的程序   引用同一个实体。

     

声明声明的名称被引入声明发生的范围,除外   存在friend说明符(11.3),某些用于详细类型说明符(7.1.6.3),以及    using-directives (7.3.4)改变了这种一般行为。

这些例外都不相关,因为我们讨论的是 using-declarations 而不是 using-directives 。让我稍微改变你的例子,以避免全局命名空间:

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

首先,N::i是在名称空间N中声明的实体,并引入N的范围。现在,让我们添加一个 using-declaration

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

从[namespace.udecl],我们有:

  

如果 using-declaration 命名构造函数(3.4.3.1),它会隐式声明一组构造函数   出现使用声明的类(12.9);否则 using-declaration 中指定的名称是a   同义词,用于另一个命名空间或类中的一组声明。

using-declaration using N::i没有命名构造函数,因此它不是名为i的新实体,而是同义词< / em> for N::i

基本上,两个i都是在各自的命名空间中引入和声明的名称。在N中,i声明具有静态链接的实体,但在B中,i声明该实体的同义词 - 而不是新实体。

答案 1 :(得分:0)

  

声明区域中声明的名称是什么意思   使用声明发生在哪里?

我会尝试用我对它的理解来回答这个问题(参考我在描述的代码中的评论):

// "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

下面是一个示例,其中(编译器)错误清楚地表明名称不可见的地方:

#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;
}