【问题标题】:Is it a defect when the base class is a dependent type当基类是依赖类型时是否有缺陷
【发布时间】:2020-07-06 08:06:54
【问题描述】:

考虑标准中的一个例子

Example

template<class T> struct A {
  typedef int M;
  struct B {
    typedef void M;
    struct C;
  };
};

template<class T> struct A<T>::B::C : A<T> {
  M m;                          // OK, A<T>​::​M
};

评论说M指的是A&lt;T&gt;::M,我对此表示怀疑,因为这些规则:

temp.dep#3

在类或类模板的定义中,在非限定名称查找期间,无论是在类模板或成员的定义点还是在实例化期间,都不会检查依赖基类的范围类模板或成员的名称。

这意味着在非限定名称查找期间永远不会考虑依赖基类范围内的名称。

名称M 是一个非限定名称。因此不考虑在A&lt;T&gt; 中声明的M

然后根据不合格名称查找的规则,即:

basic.lookup.unqual#8

对于类 X 的成员,在成员函数体、默认参数、noexcept 说明符、非静态数据成员的大括号或等号初始化器中使用的名称,或在 X 的定义之外的类成员的定义,在成员的 declarator-id32 之后,应以下列方式之一声明:

  • 如果 X 是 Y 类的嵌套类,则应是 Y 的成员,或者应是 Y 的基类的成员(此查找依次适用于 Y 的封闭类,从最里面的封闭类开始)

由于CB的嵌套类,因此我认为查找应从B开始,然后是A,因为B范围内有一个名称M,因此应停止查找。

在 [basic.lookup.unqual] 中列出的所有情况下,将按照每个相应类别中列出的顺序搜索范围以查找声明;名称查找在找到名称声明后立即结束。如果没有找到声明,则程序格式错误。

因此,根据这些规则,A&lt;T&gt;::B::C 中的名称M 应指代B::M

outcome 在这里。

GCC 同意标准所说的,但是clang 报告了一个错误并表示M 的类型是voidclang 的结果与我的分析一致。基于这些原因,我同意clang 是对的。 所以,我想知道这是一个缺陷吗?还是我误会了什么?

【问题讨论】:

标签: c++ templates c++17 language-lawyer


【解决方案1】:

根据C++ Defect Report Support in Clang,目前(2020-07-06)Clang没有实现CWG591的解析,其中定义依赖基类的段落和你引用的Example在问题中添加了。

【讨论】:

  • 哦,我错过了依赖基类的定义。
猜你喜欢
  • 2016-12-21
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
相关资源
最近更新 更多