如何解决重新定义类型名称是否合法?
C++ Primer 一书的第 7.4.1 章内容如下:
通常,内部作用域可以从外部作用域重新定义名称,即使该名称已在内部作用域中使用。但是,在类中,如果成员使用外部作用域中的名称并且该名称是类型,则该类随后可能不会重新定义该名称
subsequently 这个词让我觉得在类中使用了类型名后重新定义它只是一个错误。然而,两段之后它说:
这是否意味着即使在类中使用类型名称之前重新定义类型名称也是错误的?
解决方法
似乎引用的是以下案例
typedef int T;
struct A
{
T a[10];
typedef double T;
};
这是由于在类定义中重新声明了名称 T
的代码格式错误,该名称已在数据成员 a
的声明中使用。
如果你只会写
typedef int T;
struct A
{
int a[10];
typedef double T;
};
那么这段代码是正确的。名称 T
不用作类 A 成员声明中的类型说明符。
OP 在评论区写道:
...我的问题是[原文如此]在类中使用类型名称之前重新定义类型名称是否合法。
答案是肯定的。在一个类中定义一个类型名称来隐藏封闭范围中的类型名称是合法的。以下是不允许的:
- 一个名字,称之为
T
(虽然它不需要是一个类型),在类中使用,名字查找找到一些声明D
,并且 - 该类声明了一个名为
T
的成员,并且 - 在类完全定义之后,如果编译器返回并解析以前使用的名称
T
,它现在会找到新的成员声明而不是 {{1} }.
让我们通过几个例子来澄清这个问题。
D
上面的例子是合法的,因为当编译器看到using T = X;
class C {
using T = Y;
T x;
};
时,它已经看到了T x;
,所以using T = Y;
只能解析为T
。类中没有后续声明可以稍后更改含义。
Y
上面的例子是非法的。编译器首先查找 using T = X;
class C {
T x;
using T = Y;
};
并发现 T
的封闭定义为 T
,因为 X
尚未声明。但是在声明 C::T
之后,它意味着如果要重新解释 C::T
,那么 T x;
现在将改为引用 T
,因为类作用域优先于封闭范围。
C::T
上面的例子是非法的。 using T = ::X;
class C {
T x;
using T = ::X;
};
的两个声明使它指向同一类型这一事实并不相关。发生冲突是因为 T
会在类完全定义后发现 T x;
的不同声明。
T
上面的例子是合法的。声明 using T = X;
class C {
::T x;
using T = Y;
};
不会改变 using T = Y;
的含义,因为 ::T
将始终引用全局声明,即使 ::T
存在。
C::T
上面的例子是合法的。 using T = X;
class C {
void foo() { T x; }
using T = Y;
};
的主体是一个完整类上下文,这意味着 foo
的名称查找在看到整个类之后才会进行。换句话说,声明 T
在某种意义上总是“先于”using T = Y;
的主体,因此这类似于第一个示例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。