This code compiles and works only when calling CRTP's methods:
template <typename CRTP>
struct crtp
{
// using type = typename CRTP::type; // will not compile
void print() const
{
using type = typename CRTP::type; // compiles
static_cast<const CRTP&>(*this).print();
}
};
#include <iostream>
int main()
{
struct foo : crtp<foo>
{
using type = int;
void print() const {
std::cout << "John Cena\n";
};
} f{};
const crtp<foo>& c = f;
c.print();
return 0;
}
Upon crtp<foo>
's instantiation, foo is incomplete. But its methods can be used.
However, CRTP's types can't used dues CRTP's incompleteness outside functions.
Why is it allowed to defer a check for incompletness until a class's function is called, but not upon object's instatiation?
When using CRTP::type
within the class body (uncommented), one will get a compilation error:
<source>:4:33: error: no type named 'type' in 'foo'
using type = typename CRTP::type; // will not compile
~~~~~~~~~~~~~~~^~~~