Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CRTP base constructor crashes because child is not constructed

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?

like image 409
Andreas Pasternak Avatar asked Mar 05 '23 23:03

Andreas Pasternak


1 Answers

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.

like image 132
Lightness Races in Orbit Avatar answered Apr 28 '23 01:04

Lightness Races in Orbit