The following classes implement CRTP. I would like for class Derived
to use the constructor provided by Base
, so I write using
. However, I get the error message, "can only inherit constructor from direct base". Equivalently for the member variable x
.
template<template<typename, size_t> typename G, typename F, size_t U>
struct Base
{
double x;
Base(double x) : x{ x } {}
double gimme_x()
{
return (*static_cast<G<F, U>*>(this)).gimme_x();
}
};
template<typename F, size_t U>
struct Derived : Base<Derived, double, U>
{
using Base<Derived, double, U>::Base;
using Base<Derived, double, U>::x;
double gimme_x()
{
return x + 1.8;
}
};
This problem can be mitigated by changing the template-template implementation of Base
to just use a regular template.
template<typename G, typename F, size_t U>
struct Base
{
double x;
Base(double x) : x{ x } {}
double gimme_x()
{
return (*static_cast<G*>(this)).gimme_x();
}
};
template<typename F, size_t U>
struct Derived : Base<Derived<F, U>, double, U>
{
using Base<Derived<F, U>, double, U>::Base;
using Base<Derived<F, U>, double, U>::x;
double gimme_x()
{
return x + 1.8;
}
};
While the second one looks a bit more verbose, it seems like it should be equivalent to the first one in this case. What's the difference and why does the implementation of the first one fail?