什么名称查找规则适用于静态 const 数据成员定义中的名称
Posted
技术标签:
【中文标题】什么名称查找规则适用于静态 const 数据成员定义中的名称【英文标题】:What name lookup rule apply to the name in the definition of static const data member 【发布时间】:2014-05-30 04:30:22 【问题描述】:在数据成员的 quialified-id 之后,有一个引用描述的名称查找应用于 const 静态数据成员的数据成员:
秒。 3.4.1/13:
用于定义类 X 的静态数据成员的名称 (9.4.2) (在静态成员的限定 ID 之后)被查找为 如果该名称在 X 的成员函数中使用。
但是我们可以定义类内的静态常量数据成员:
class A
static const int i = x;//x is a name defined an arbitrary const int
;
从秒的规则。 3.4.1/13 不适用于名称x
查找。 实际会应用什么规则?请参考标准中的相应条款。
例如,下面的代码是有效的:
#include <stdio.h>
const int a=5;
class A
public:
static const int b=a;//b is unqualified-id of this data-member
;
int main() printf("%d\n",A::b); //5
以下代码也有效:
#include <stdio.h>
class A
public:
static const int a=7;
static const int b=a;
;
int main() printf("%d\n",A::b); //7
但以下无效:
#include <stdio.h>
class A
public:
static const int b=a; //error: a was not declare in this scope.
static const int a=7;
;
int main() printf("%d\n",A::b);
不清楚哪些规则适用于查找a
。
【问题讨论】:
x
在您的案例中定义在哪里?显然它不能只是任何地方。
我不明白这个问题;您引用的文字是说查找与 void member() x;
的查找相同。您是在问如何在成员函数中查找名称?
@Praetorian x 在某处定义。我想了解范围的后续查找名称x。
@MattMcNabb No. 引用说此查找与 quailified-id 相同。但是使用静态 const 数据成员的非限定 id 查找呢?
您将术语合格和不合格查找与 qualified-id 混为一谈。后者在此引用中谈论的是静态数据成员标识符 (i
),当您提供定义时需要使用类名(和命名空间名称)进行限定 - 例如,const int NS::A::i;
- 因此短语 qualified-id。 §3.4.1/13 是说 §3.4.1/8 下列出的规则将用于查找x
。
【参考方案1】:
静态数据成员的类内声明不是定义,即使它包含初始化程序。因此 §3.4.1/13 不适用于您的示例。
类范围内的名称查找由哪些范围到达类范围的规则定义。 §3.3.7/1.1:
在类中声明的名称的潜在范围不仅包括名称声明点之后的声明区域, 还有所有函数体,默认参数, 异常规范和大括号或等式初始化器 该类中的非静态数据成员(包括嵌套中的此类内容 类)。
在类 S 中使用的名称 N 应在其上下文中引用相同的声明,并且在 S 的完整范围内重新评估时。否 违反此规则需要进行诊断。
如果对类中的成员声明重新排序会在 (1) 和 (2) 下产生一个替代的有效程序,则该程序是非良构的,不会 需要诊断。
这些规则的目的是允许成员函数访问稍后在类中声明的成员变量。因为规则没有提到静态数据成员的初始化器,所以从静态数据成员中查找名称默认为 3.4.1/7:
在成员之外的类 X 的定义中使用的名称 函数体、默认参数、异常规范、 非静态数据成员的大括号或相等初始化器,或嵌套 类定义应以下列方式之一声明:
该列表基本上归结为“名称必须是同一类的成员,或者在封闭范围内声明。”在您的第一个示例中,a
在封闭的命名空间中声明,因此可以找到它。在第二个示例中,a
在使用前声明。
但在第三个示例中,它在被声明为非法之前使用——如果在封闭的命名空间中有一些 a
的声明,由于 3.3.7/1.2,这将是未定义的行为。
【讨论】:
那么什么规则将应用于我的示例?我不明白。 谢谢!我理解你。【参考方案2】:#include <stdio.h>
const int a=5;
class A
public:
static const int b=a; // The quote corresponds to the lookup for a.
// It says that the lookup logic for a is the same
// as the lookup for a name in a member function of A
;
如果你有成员函数,让我们把它设为static
以便于比较,让我们看看函数中名称的查找是什么样的。
class A
public:
static void fun()
b = a;
// The lookup for a:
// 1. A local variable in the function.
// 2. A `static` member of the class.
// 3. A variable in the enclosing namespace.
static const int b;
;
当你使用
static const int b = a;
a
的查找将来自函数 foo
的 (2) 和 (3),因为 a
不能是局部变量。
【讨论】:
以上是关于什么名称查找规则适用于静态 const 数据成员定义中的名称的主要内容,如果未能解决你的问题,请参考以下文章