当基类是依赖类型时,这是一个缺陷吗

Is it a defect when the base class is a dependent type

本文关键字:缺陷 一个 依赖 基类 类型      更新时间:2023-10-16

考虑标准中的一个示例

示例

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<T>::M,我对此表示怀疑,因为这些规则:

温度dep#3

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

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

名称M是非限定名称。因此,不考虑在A<T>中声明的M

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

basic.lookup.uqual#8

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

  • 如果X是类Y的嵌套类,应是Y的成员,或应是Y基类的成员(此查找反过来适用于Y的封闭类,从最内部的封闭类开始(

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

在〔basic.lookup.uqual〕中列出的所有情况下,将按每个类别中列出的顺序搜索范围以查找声明;一旦找到名称的声明,名称查找就结束。如果找不到声明,则表示程序格式不正确。

因此,根据这些规则,A<T>::B::C中的名称M应指B::M

结果就在这里。

GCC同意标准的说法,但clang报告了一个错误,并表示类型Mvoid。CCD_ 18的结果与我的分析一致。基于这些原因,我同意clang是正确的。所以,我想知道这是一个缺陷吗?或者我误解了什么?

根据Clang的C++缺陷报告支持,目前(2020-07-06(Clang没有实现CWG591的解决方案,其中添加了带有依赖基类定义的段落和您在问题中引用的示例。