什么名称查找规则适用于静态 const 数据成员定义中的名称

What name lookup rule apply to the name in the definition of static const data member

本文关键字:数据成员 定义 const 适用于 查找 规则 什么 静态      更新时间:2023-10-16

在数据成员的quialified-id之后,有一个引号描述了应用于常量静态数据成员的数据成员的名称查找:

第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("%dn",A::b); } //5

以下代码也有效:

#include <stdio.h>
class A
{
public:
    static const int a=7;
    static const int b=a;
};
int main(){ printf("%dn",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("%dn",A::b); }

目前尚不清楚哪些规则适用于查找a

静态数据成员的类内声明不是定义,即使它包含初始值设定项也是如此。因此,§3.4.1/13 不适用于您的示例。

类作用域

中的名称查找由作用域到达类作用域的规则定义。 §3.3.7/1.1:

  1. 在类中声明的名称的潜在作用域不仅包括名称声明点后面的声明性区域, 还有所有函数体,默认参数, 异常规范和大括号或等号初始值设定项 该类中的非静态数据成员(包括嵌套中的此类内容( 类(。

  2. 在S类中使用的名称N应在其上下文中以及在S的已完成范围内重新评估时引用相同的声明。 否 违反此规则需要诊断。

  3. 如果对类中的成员声明重新排序会产生 (1( 和 (2( 下的备用有效程序,则程序格式不正确,否 需要诊断。

这些规则的目的是允许成员函数访问稍后在类中声明的成员变量。由于规则未提及静态数据成员的初始值设定项,因此静态数据成员的名称查找默认为 3.4.1/7:

成员之外的类 X 的定义中使用的名称 函数体、默认参数、异常规范、 非静态数据成员的大括号或等于初始值设定项,或嵌套 类定义应通过以下方式之一声明:

该列表基本上可以归结为"名称必须是同一类的成员,或者在封闭作用域中声明"。在第一个示例中,a 是在封闭命名空间中声明的,因此可以找到它。在第二个示例中,a在使用之前声明。

但是在第三个示例中,它是在声明之前使用的,这是非法的 - 如果在封闭命名空间中声明了一些a,则由于 3.3.7/1.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不能是局部变量。