【问题标题】:What is the rule that allows `this->` to access members of dependent base classes?允许 `this->` 访问依赖基类成员的规则是什么?
【发布时间】: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-&gt;x 会怎样?现在名称x 是依赖的,它的查找被推迟到实例化。但引用的段落似乎暗示 x 不应该找到即使在实例化时, 因为在 this-&gt;x 中查找 x仍然 不合格的查找。

显然,实现的行为不是这样的,而且人们普遍认为,一旦模板被实例化,就会搜索基类范围

  1. 我是否误解了引用的段落?
  2. 是否有指定“正确”行为的段落?

【问题讨论】:

  • 这不是非限定查找(3.4.1 [basic.lookup.unqual]),这是类成员访问表达式查找(3.4.5 [basic.lookup.classref])。
  • @n.m.谢谢,我没有意识到类成员名称查找是一种不同类型的名称查找。你应该这样回答。
  • 究竟什么是“依赖基类”?而不是说一个独立的基类?有这种事吗?
  • @EJP 在template &lt;typename T&gt; struct C : B { ... } 中,B 不是依赖基类。

标签: c++ templates language-lawyer name-lookup dependent-name


【解决方案1】:

类成员访问表达式 (5.2.5. [expr.ref]) 不使用非限定查找规则,它们使用类成员访问查找规则 (3.4.5 [basic.lookup.classref])。

(2) 如果类成员访问(5.2.5)中的id-expression是非限定id,对象表达式的类型 是类类型C,则在类C 的范围内查找未限定ID。

【讨论】:

  • 这并没有真正说明为什么答案与非限定名称的答案不同(显然考虑了任何包含类的范围)。
猜你喜欢
  • 2021-06-23
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 2012-05-03
相关资源
最近更新 更多