In CRTP, the base class can use functions and variables from derived class. However, the types from derived class cannot be used directly by base class, see code below:
#include <iostream>
template <class Derived>
class A {
public:
//using Scalar = typename Derived::Scalar; // Error!
static constexpr int NA1 = Derived::NB1;
static constexpr int NA2 = Derived::NB2;
static constexpr int NA3 = Derived::NB3;
};
template <int _N = 2>
class B : public A<B<_N>> {
public:
using Scalar = double;
static constexpr int NB1 = 1;
static constexpr int NB2 = _N;
static constexpr int NB3 { sizeof(Scalar) };
};
int main(int argc, char** argv)
{
using Type = B<2>;
std::cout << Type::NA1 << ' '
<< Type::NA2 << ' '
<< Type::NA3 << '\n';
}
// output:
// 1 2 8
If the line using Scalar = typename Derived::Scalar;
is uncommented, an error occurs:
main.cpp:6:11: error: invalid use of incomplete type 'class B<2>'
I know that the type (Scalar
) can be passed to base class as a template parameter, but why can't it be used just like the variables? Is it just a language rule? Or is there any logical restriction that makes this unable to implement?