c++ - 基类是依赖类型时是否存在缺陷

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

考虑标准中的一个例子
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<T>::M ,我对此表示怀疑,因为这些规则:
temp.dep#3

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.


这意味着在非限定名称查找期间永远不会考虑依赖基类范围内的名称。
姓名 M是一个不合格的名字。因此 M声明于 A<T>不考虑。
然后根据不合格名称查找的规则,即:
basic.lookup.unqual#8

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)


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

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.


因此,根据这些规则,名称 MA<T>::B::C应引用B::M .
outcome在这儿。
GCC 同意标准所说的内容,但是 clang报错,表示类型Mvoid . clang的结局|和我的分析一致。基于这些原因,我同意clang是对的。
所以,我想知道这是一个缺陷吗?或者我误解了什么?

最佳答案

根据 C++ Defect Report Support in Clang , 目前 (2020-07-06) Clang 没有执行 CWG591 的决议,其中添加了具有依赖基类定义的段落和您在问题中引用的示例。

关于c++ - 基类是依赖类型时是否存在缺陷,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62751773/

相关文章:

c++ - 基于派生类型的编译时行为分支

c++ - cgo 调用在 C++ 中定义的函数(在命名空间中)

c++ - 在命名空间中定义一个函数

html - 无法删除 SB Admin Bootstrap 模板中的侧边栏

c# - 如何在此处应用 C# 中的 "template"或 "skeleton"代码?

c++ - 函数模板不识别左值

c++ - 引用 std::shared:ptr 以避免引用计数

c++ - Open Babel C++ API 为什么他们的自定义迭代器不能直接用作函数的参数?

c++ - 写入WAV文件时定期创建静音

c++ - 如果 constexpr 给出错误,则实例化模板函数为 false