CRTP (Curiously Recurring Template Pattern) is a very useful skill to achieve static polymorphism.
How to achieve CRTP if the derived class is a template class? Here is an example.
#include <iostream>
#include <string>
using namespace std;
// Base class A
template< typename Type, template< typename > class Derived >
class A {
public:
A() = default;
virtual ~A() = default;
void output( Type num ) {
cout << "From base A, ";
static_cast< Derived< Type > * > (this)->speak( num );
}
protected:
virtual void speak( Type num ) = 0;
};
// Derived class B, override the protected method speak()
template< typename Type >
class B : public A< Type, B > {
friend class A< Type, B >;
public:
using A< Type, B >::A;
protected:
void speak( Type num ) override {
cout << "I am B, and I got " << std::to_string( num ) << endl;
}
};
// Derived class C, override the protected method speak()
template< typename Type >
class C : public A< Type, C > {
friend class A< Type, C >;
public:
using A< Type, C >::A;
protected:
void speak( Type num ) override {
cout << "I am C, and I got " << std::to_string( num ) << endl;
}
};
// Client code
int main(int argc, char** argv) {
B< float > b;
b.output( 5 );
C< float > c;
c.output( 8 );
return 0;
}
Use g++ to compile the above code, and get the outputs.
g++ -o crtptest main.cpp --std=c++14
./crtptest
From base A, I am B, and I got 5.000000
From base A, I am C, and I got 8.000000