base class 是依赖类型时是缺陷吗
Is it a defect when the base class is a dependent type
考虑标准中的一个例子
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
,我对此表示怀疑,因为这些规则:
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
这意味着在非限定名称查找过程中永远不会考虑依赖基 class 范围内的名称。
名称 M
是一个不合格的名称。因此,不考虑在 A<T>
中声明的 M
。
然后根据不合格名称查找规则,即:
For the members of a class X, a name used in a member function body, in a default argument, in a noexcept-specifier, in the brace-or-equal-initializer of a non-static data member, or in the definition of a class member outside of the definition of X, following the member's declarator-id32, shall be declared in one of the following ways:
- if X is a nested class of class Y, shall be a member of Y, or shall be a member of a base class of Y (this lookup applies in turn to Y's enclosing classes, starting with the innermost enclosing class)
由于 C
是 B
的嵌套 class,因此我认为查找应从 B
开始,然后是 A
,因为有B
范围内的名称 M
,因此应停止查找。
In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
因此,根据这些规则,A<T>::B::C
中的名称 M
应指代 B::M
。
outcome在这里。
GCC 同意标准所说的内容,但是 clang
报告了一个错误并表示类型 M
是 void
。 clang
的结果和我的分析一致。根据这些理由,我同意clang
是对的。
所以,我想知道这是一个缺陷吗?或者我误解了什么?
根据 C++ Defect Report Support in Clang, currently (2020-07-06) Clang does not implement the resolution of CWG591,添加了 依赖基础 class 定义的段落和您在问题中引用的示例。
考虑标准中的一个例子
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
,我对此表示怀疑,因为这些规则:
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
这意味着在非限定名称查找过程中永远不会考虑依赖基 class 范围内的名称。
名称 M
是一个不合格的名称。因此,不考虑在 A<T>
中声明的 M
。
然后根据不合格名称查找规则,即:
For the members of a class X, a name used in a member function body, in a default argument, in a noexcept-specifier, in the brace-or-equal-initializer of a non-static data member, or in the definition of a class member outside of the definition of X, following the member's declarator-id32, shall be declared in one of the following ways:
- if X is a nested class of class Y, shall be a member of Y, or shall be a member of a base class of Y (this lookup applies in turn to Y's enclosing classes, starting with the innermost enclosing class)
由于 C
是 B
的嵌套 class,因此我认为查找应从 B
开始,然后是 A
,因为有B
范围内的名称 M
,因此应停止查找。
In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
因此,根据这些规则,A<T>::B::C
中的名称 M
应指代 B::M
。
outcome在这里。
GCC 同意标准所说的内容,但是 clang
报告了一个错误并表示类型 M
是 void
。 clang
的结果和我的分析一致。根据这些理由,我同意clang
是对的。
所以,我想知道这是一个缺陷吗?或者我误解了什么?
根据 C++ Defect Report Support in Clang, currently (2020-07-06) Clang does not implement the resolution of CWG591,添加了 依赖基础 class 定义的段落和您在问题中引用的示例。