【发布时间】:2015-09-19 06:47:04
【问题描述】:
我们知道,下面的代码格式不正确,因为成员 x 在依赖基类中。但是,将指定行上的 x 更改为 this->x 将修复错误。
template <typename T>
struct B {
int x;
};
template <typename T>
struct C : B<T> {
void f() {
int y = x; // Error!
}
};
int main() {
C<int> c;
c.f();
}
我想解释一下标准中如何指定此行为。根据[temp.dep]/3:
在类或类模板的定义中,如果一个基类依赖于一个模板参数,基类 在类模板的定义点处,在非限定名称查找期间不检查范围 或成员或在类模板或成员的实例化期间。
这似乎解释了为什么单独使用 x 会失败。在定义点查找名称x,不检查基类范围。但是,如果我们使用this->x 会怎样?现在名称x 是依赖的,它的查找被推迟到实例化。但引用的段落似乎暗示 x 不应该找到即使在实例化时, 因为在 this->x 中查找 x 是 仍然 不合格的查找。
显然,实现的行为不是这样的,而且人们普遍认为,一旦模板被实例化,就会搜索基类范围。
- 我是否误解了引用的段落?
- 是否有指定“正确”行为的段落?
【问题讨论】:
-
这不是非限定查找(3.4.1 [basic.lookup.unqual]),这是类成员访问表达式查找(3.4.5 [basic.lookup.classref])。
-
@n.m.谢谢,我没有意识到类成员名称查找是一种不同类型的名称查找。你应该这样回答。
-
究竟什么是“依赖基类”?而不是说一个独立的基类?有这种事吗?
-
@EJP 在
template <typename T> struct C : B { ... }中,B不是依赖基类。
标签: c++ templates language-lawyer name-lookup dependent-name