Double derived class produces error unless call to Base

Viewed 77

The following code causes my compiler to produce two errors: type name is not allowed and expected 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();
}

The issue is the line print_pi<int>() in the test() function of the DoubleDerived class. However, if this is changed to Base::print_pi<int>() everything compiles without error. What is going on here and is changing to the Base function call the only way around this issue? Additionally, why doesn't this happen if the test() function were to be in the Derived class?

Edit: The associated answer listed above still causes errors on some compilers (NVCC) so I cannot endorse that question as an actual substitute.

2 Answers

In the class Derived the name print_pi is a dependent name.

You can use for example

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

or

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

I think that may be because you now have a print_pi() in Base, and another one in Derived class. The compiler has difficulty determining which function you want to use.

As you use template function as a class member function, that function cannot be virtual. Can a class member function template be virtual?

Personally I'd suggest to remove the base class, and write print_p1 as a template function.

Edit1: godbolt.org/z/rWzjrvT69 Here is the code that illustrates that we can use the base function in derived class.

Related