You can use CRTP to solve the problem, but the types have to be known at compile time. For example:
#include <iostream>
template <template <typename> class CLASS, typename T>
class Mother
{
public:
T get() const { return static_cast<const CLASS<T>*>(this)->get();}
};
template <typename T>
class Child: public Mother<Child, T>
{
public:
Child(T x) : v{x} {}
T get() const {return v;}
T v;
};
// Função criada só para mostrar a herança estática funcionando
template <template <typename> class CLASS, typename T>
T doit(const Mother<CLASS, T>& x)
{
return x.get();
}
int main()
{
auto f = Child<float>(6.6); // f é do tipo Child<float>
auto c = Child<int>(5); // c é do tipo Child<int>
Mother<Child, int> m = c; // m é do tipo Mother<Child, int>
std::cout << doit(c) << std::endl;
std::cout << doit(f) << std::endl;
}
Note that you can now call the function doit
even if the return types are different
See working at Coliru