I have classes which are autogenerated but I want to enable end users to add custom member functions and constructors.
My approach is to use a CRTP base class which has no member variables just functions.
The problem lies with the constructor. If I define a constructor in my CRTP I cannot correctly access the child as it is not constructed yet as the child classes constructor only gets called after the CRTP base is constructed.
#include <iostream>
#include <string>
template<class Child>
struct Foo {
Foo(std::string i) {
// Childs constructor is not run yet.
std::cout << static_cast<Child&>(*this).d.size(); // Prints trash
static_cast<Child&>(*this).d = i; // Segfault here
(void) i;
}
};
// Cannot change this class.
struct Bar : Foo<Bar> {
using base_t = Foo<Bar>;
using base_t::base_t;
std::string d;
};
int main()
{
Bar bar("asdgasdgsag");
std::cout << "bar.d: " << bar.d << std::endl;
}
Is there a way to solve this problem?
Your base constructor can't do things with the child class. At all. The latter hasn't been constructed yet.
CRTP allows other member functions of Foo
to do so, but that's about it.
There's no "quick fix" within the design you've come up with. You can either add a Init
-like function to Foo
to do this stuff later (and invoke it from the child's ctor), or (ideally) rethink your approach.
It's a bit odd that you can't modify the child class but are adding things to the Base
— that's not how inheritance is supposed to be done, and it seems like you're trying to use CRTP to hack around that, but have found out why this is not a valid hack.
Without knowing what you're trying to accomplish I can't be more precise than that.
Maybe a factory function can help you? Or inherit from Bar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With