【问题标题】:Should name lookup be deferred for a class/namespace-name qualified by this-> in a class template definition?是否应该在类模板定义中为由 this-> 限定的类/命名空间名称延迟名称查找?
【发布时间】:2013-07-07 20:57:49
【问题描述】:

clang 3.0 和 g++ 4.8.1 都拒绝以下代码,并在注释中显示错误:

template<typename T>
struct S
{
    void f()
    {
        this->dependent(); // no error: type of 'this' is dependent?
        this->Dependent::dependent(); // error: 'Dependent' has not been declared
    }
};

根据[basic.lookup.classref]

. 后面的类名或命名空间名。 or -> 运算符在整个后缀表达式的上下文和对象表达式的类范围内查找。

和[temp.dep.expr]

如果封闭的成员函数的类类型是依赖的,this 是类型依赖的。

如果类或命名空间名称Dependent在对象表达式的类的范围内查找*this,并且对象表达式的类是依赖的,是否应该不推迟此查找直到模板被实例化?标准是否规定了正确的行为?

编辑:clang 3.0 接受以下代码,但 g++4.8 给出与上述相同的错误

template<typename T>
struct S
{
    T m;
    void f()
    {
        m.dependent();
        m.Dependent::dependent();
    }
};

【问题讨论】:

  • 我看不出this-&gt;Dependent::dependent() 怎么可能是一个依赖表达式。它如何依赖于模板参数?
  • [temp.dep.expr] "this 是类型相关的,如果封闭成员函数的类类型是相关的"。
  • 第二个代码是有意义的,因为它可能依赖于模板而不是第一个。对我来说,第一个和第二个代码在 clang3、g++4.8.1 和 msvc_110 上都编译得很好,除非我当然尝试实例化第一个代码
  • clang 3.0 还是 3.2? clang 3.0 肯定会拒绝第一个代码片段。

标签: c++ templates language-lawyer


【解决方案1】:

在您的第一个代码中,两行都是“格式错误,不需要诊断”,因为“this”指的是当前实例化,但没有找到任何成员,并且类模板没有依赖的基类。

它既不是当前实例化的成员,也不是未知特化的成员。见 14.6.2.1p6

【讨论】:

  • 您引用的是哪个版本的标准?我猜这种语言是从 C++03 开始​​添加的。
  • @willj 即使在 C++03 中它也是“格式错误的,NDR”,但是没有针对它的特定规则,只是一般的“如果无法生成有效的特化,则模板格式错误;NDR”。现在我们有了具体的规则。
  • 所以一个类算作一个“复合类型”,由它的“成员序列和基类对象”组成,在这种情况下,this 是依赖的,如果它的类型有一个依赖的基类?
  • @willj "this" 始终依赖于模板。但这并不意味着this-&gt;foo 一定是依赖的。
猜你喜欢
  • 2013-08-15
  • 2015-04-11
  • 1970-01-01
  • 2013-08-14
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
相关资源
最近更新 更多