首页 > 解决方案 > 使用基类的注入类名称进行限定的依赖名称查找

问题描述

最新版本的 clang、gcc 和 msvc (/permissive-) 都拒绝以下代码:

struct B {
    void func() {}
};

template<typename T>
struct Base : B {
    void func() {}
};

template<typename T>
struct Derived : Base<T> {
    void func() {
        this->Base::func(); // (*) fails here, even though this->B::func(); works
    }
};

// for msvc, use /permissive- and the following instantiation for the error to trigger:
int main() {
    Derived<void> d;
    d.func();
}

根据https://eel.is/c++draft/temp#dep.type-6.3 ,我对当前标准的理解是 (*) 被认为是未知专业的成员,因此,名称解析将是延迟到模板实例化,但考虑到 (*) 也是一个合格的函数调用,即使它是依赖的,也应该在基类中执行查找,然后它应该找到注入的类名:。Base

这段代码真的无效还是编译器错误?我错过了什么?

标签: c++c++20

解决方案


在类成员访问表达式this->Base::func中,id 表达式是Base::func。在这个表达式里面,Base不是未知专业的成员。

如果您希望它成为未知专业的成员,则必须使用注入的类名对其进行限定:

template<typename T>
struct Derived : Base<T> {
    void func() {
        this->Derived::Base::func(); // compiles: Base is now a member of an unknown specialization
    }
};

推荐阅读