来自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? */
答案 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;
}