声明名称、引入名称和声明实体之间的区别
The difference between declaring a name, introducing a name, and declaring an entity
来自c++ 11标准,§7.3.3[namspace .udecl]/1:
using声明将一个名称引入using声明所在的声明区域。
using声明:
using typename
optnested-name-specifier unqualified-id;
using ::
unqualified-id;
在using声明中指定的成员名在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? */
从第一原则来看,实体是,从[basic]
值、对象、引用、函数、枚举数、类型、类成员、位域、模板、模板特殊化、命名空间、参数包或
this
。[…表示实体的每个名称都由声明引入。
声明声明事物。被声明意味着它是由声明引入的,从[basic.scope.declarative]
这些异常在这里都不相关,因为我们讨论的是using-declarations,而不是using-directives。让我稍微修改一下您的示例,以避免使用全局命名空间:每个名称都是在程序文本中称为声明性区域的某个部分引入的,这是最大的部分在该程序中,该名称是有效的,也就是说,该名称可以用作非限定名称指同一实体
由声明声明的名称被引入到该声明发生的作用域中,除非
friend
说明符的存在(11.3),详细类型说明符的某些使用(7.1.6.3),以及using-directives(7.3.4)改变这种一般行为。
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
} // +
从[名称空间。,我们有:
如果using-declaration命名一个构造函数(3.4.3.1),它隐式地声明一组构造函数出现using声明的类(12.9);否则,使用声明在中指定的名称是同义词表示另一个命名空间或类中的一组声明。
using-declaration using N::i
没有命名构造函数,所以i
不是一个新的实体,而是N::i
的同义词。
所以基本上,两个i
都是在各自的名称空间中引入和声明的名称。在N
中,i
声明了一个具有静态链接的实体,但在B
中,i
声明了该实体的同义词,而不是新实体。
在声明性区域中声明的名称是什么意思using声明发生在哪里?
我将尝试用我对它的理解的一个例子来回答这个问题(参考我在描述的代码中的注释):
// "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;
}
- 在.cpp文件之间传递结构声明,而不使用全局头文件
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- 如何声明不同类型的模板化类之间的转换
- 类型测试对象的动态数组的这两个声明之间的区别?
- C++ 中的类之间的数据重新循环 - 错误:'<class name>'未在此范围内声明
- 重复符号 --- 定义和声明之间的差异
- 以下声明之间的区别
- 一条线和两行声明之间的差异
- 恒定声明全局或在使用它的函数中声明恒定声明之间有什么区别?
- 在构造函数中创建数组与在 C++ 中创建声明之间的区别
- 以下声明之间的区别是什么
- 以下声明之间的区别
- pimpl 最终用户的全局远向声明与私有远向声明之间的区别
- C++中include指令和forward声明之间的区别
- 这两个与灰泥相关的声明之间有区别吗
- 2D矢量声明之间的区别
- c++0x:解决函数定义后接空声明和简单声明之间的歧义
- 带有 extern 和没有 extern 的函数的本地/块范围声明之间的区别
- C中的这些声明之间有什么区别