声明与 const 变量和成员函数相同的标识符
Declare the same identifier as const variable and member function
我写了以下一段代码
#include <iostream>
const int N = 5;
class X
{
public:
int array[N];
void foo()
{
std::cout << "array size:"<<sizeof(array)/N << std::endl;
}
enum
{
N = 3
};
};
int main()
{
X x;
x.foo();
}
上述代码无法使用 GCC 编译:
<source>:13:8: error: declaration of 'N' [-fpermissive]
N = 3
^
<source>:2:11: error: changes meaning of 'N' from 'const int N' [-fpermissive]
const int N = 5;
^
从编译时开始,数组被定义为一个由五个整数组成的数组,N 被定义为 5。 编译器如何解析变量的名称声明?
在成员函数的作用域内(即使是内联定义的函数(,该类被认为是完整的1。因此,使用N
那里必须使用成员枚举器。并且其值必须为 3。
但是,在声明类成员数据时,情况并非如此。此时(指定array
时(,该类不被视为完整。因此,N
只能引用之前看到的内容,这意味着它必须是全局常数。
叮当接受它,但发出6
(sizeof(int) * 5 / 3
(。GCC (8( 没有,但它并不是真正的无效代码。只是容易出错。更好地定义的方法是在定义数组之前将枚举器移动到
enum { N = 3 };
int array[N];
。或者如果我们不这样做,那么我们可以使用范围解析来引用"正确的 N">
sizeof(array) / ::N
重新排列类定义会更好,因为它仍然不会出错(我们可以忘记使用限定::N
(。
1:来自最新的C++标准草案
[类记忆]/6
类的完整类上下文是
- 函数体 ([dcl.fct.def.general](,
- 默认参数 ([dcl.fct.default](,
- 无例外说明符,
- 合同条件([dcl.attr.contract](,或
- 默认成员初始值设定项
在类的成员规范中。
在行中
int array[N];
N
是全球N
。
在函数foo()
,N
是enum
中定义的那个。
在foo()
的定义中,类的定义用于解析名称。但是,在成员变量的声明中,只有该行之前的声明用于解析名称。
如果您将课程更改为
class X
{
public:
enum
{
N = 3
};
int array[N];
void foo()
{
std::cout << "array size:"<<sizeof(array)/N << std::endl;
}
};
然后,用于定义array
的N
是第enum
中定义的。
PS这对于理解语言很有用,但请不要在现实世界的应用程序中使用这种编码风格。
问题来自声明int array[N];
。
根据 [basic.scope.class]/2:
在 S 类中使用的名称 N 应在其上下文中引用相同的声明,并且在 S 的完整范围内重新评估时,无需诊断违反此规则的情况。
在声明的上下文中,N
被解析为引用::N
,但在已完成的X
范围内(所有成员现在都可见(,N
被解析为引用枚举器X::N
,因此程序格式不正确;不需要诊断。
- 在模板化函数中重新定义(忽略)的 SWIG 标识符
- 在 c++ 中找不到此函数的标识符
- 声明与 const 变量和成员函数相同的标识符
- 我的函数调用 (C++) 中的未声明标识符
- 函数声明中的 WINAPI 标识符C++ DLL 入口点函数中的标识符
- 由于值返回函数中的错误,程序无法编译.它说未声明的标识符
- im调用函数时找不到标识符?
- 将函数标识符作为右值引用传递并对其应用 std::move()
- 错误 C2146:语法错误:按函数传递映射时标识符 mType 之前缺少','
- C 如何从构造函数中声明(错误C2065未宣布的标识符)
- C++ 多态构造函数错误;标识符未定义
- 调用函数时未定义标识符"function_name"
- 为什么在函数参数编译中没有标识符的const关键字
- 当通过函数中的参考调用时,标识符不确定
- 在检查传递函数标识符时是否获得模板参数时遇到问题
- 函数参数中未声明和未定义的标识符
- 使用函数模板中静态局部变量的地址作为类型标识符是否安全
- C++构造函数:数字常量之前的预期标识符
- 找不到QT 5.6 update()函数标识符
- 不存在的标识符在非启用函数模板中用作默认参数