双派生 class 产生错误,除非调用 Base

Double derived class produces error unless call to Base

以下代码导致我的编译器产生两个错误:type name is not allowedexpected an expression

#include <iostream>

class Base {
protected:

    template <typename T1>
    void print_pi() {
        std::cout << (T1)3.141596 << std::endl;
    };

};

template <typename T2>
class Derived : public Base {
};

template <typename T3>
class DoubleDerived : public Derived<T3> {
public:
    void test() {
        print_pi<int>(); // This creates error, however changing to Base::print_pi<int>(); works.
    }
};

int main() {

    DoubleDerived<float> dd;
    dd.test();
}

问题出在 DoubleDerived class 的 test() 函数中的第 print_pi<int>() 行。但是,如果将其更改为 Base::print_pi<int>(),则一切都可以正常编译。这是怎么回事,更改为 Base 函数调用是解决此问题的唯一方法?此外,如果 test() 函数位于 Derived class?

中,为什么不会发生这种情况?

编辑: 上面列出的相关答案仍然会导致某些编译器 (NVCC) 出错,因此我不能认可该问题作为实际替代。

我认为这可能是因为您现在在 Base 中有一个 print_pi(),在 Derived 中有另一个 class。编译器很难确定您要使用哪个函数。

当您将模板函数用作 class 成员函数时,该函数不能是虚函数。 Can a class member function template be virtual?

我个人建议删除基础 class,并将 print_p1 写为模板函数。

Edit1: godbolt.org/z/rWzjrvT69 这里是说明我们可以在派生中使用基函数的代码 class.

在class派生的名字print_pi是一个从属名字。

你可以使用例如

template <typename T3>
class DoubleDerived : public Derived<T3> {
public:
    void test() {
        Derived<T3>::template print_pi<int>();
    }
};

template <typename T3>
class DoubleDerived : public Derived<T3> {
public:
    void test() {
        DoubleDerived::template print_pi<int>();
    }
};