I have the following setup:
#include <iostream>
template <typename T>
struct feline {
void roar() noexcept {
static_cast<T*>(this)->do_roar();
}
feline() noexcept {
std::cerr << "Feline ctor" << std::endl;
}
};
struct lion : public feline<lion> {
lion() noexcept : feline() {
std::cerr << "Lion ctor" << std::endl;
}
void do_roar() noexcept {
std::cerr << "Lion roar" << std::endl;
}
};
struct tiger : public feline<tiger> {
tiger() noexcept : feline() {
std::cerr << "Tiger ctor" << std::endl;
}
void do_roar() noexcept {
std::cerr << "Tiger roar" << std::endl;
}
};
int main()
{
feline<lion> lion;
lion.roar();
feline<tiger> tiger;
tiger.roar();
}
and when I execute it I get the following result:
Feline ctor
Lion roar
Feline ctor
Tiger roar
Which means the constructors for Lion and Tiger are never called. How can I make that happen?
Because you never create an actual lion.
CRTP requires an object of the actual class in order to work properly.
Remember that the base class will never instantiate the child class directly because its all about forcing the class to support some functions and not classical inheritance.
Your code could crash but it doesn't, and that's because the function do_roar
does not access any private variables. Try adding some members to lion
and using them in do_roar
, you'll see...
If you want a lion use the lion
class, feline<lion>
is just an instantiation of feline<T>
where T = lion
.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments