Cyclic dependent CRTP

I have a hierarchy of operations and (general) information classes, where intuitively it seems that there is no need for run-time polymorphism, and yet I cannot find a solution without it.

For this question, suppose there is a two-level hierarchy. There is a basic operation and a derivative operation. Objects from the same hierarchy level may need to exchange information between them (which means that basic mode objects need to exchange basic information, and derivative operational objects need to exchange derivative information, but basic operational objects never need to share received information or Versa flaws).

So it starts as follows:

// Shared between base operation objects class base_info { }; // Shared between derived operation objects class derived_info : public base_info { }; 

Given that there is no runtime, the question of which operation objects use common information objects, there is also the following:

 template<class Info> class base_op { std::shared_ptr<Info> m_info; }; class derived_op : public base_op<derived_info> { }; 

The rest of the code always creates base_op using base_information , and therefore no runtime polymorphism is required here.

Now, at some points, common information objects may decide that they need to spawn new operations. As you can see above, operational objects need common pointers for common information objects. Thus, the hierarchy of information is changed to this:

 // Shared between base operation objects class base_info : private std::enable_shared_from_this<base_info> { void do_something_spawning_new_ops(); }; ... 

Now the problem is how to implement do_something_spawning_new_ops . With runtime polymorphism, this is not so difficult:

 class base_info : private std::enable_shared_from_this<base_info> { void do_something_spawning_new_ops() { // Need a new op. get_op_shared_ptr(); } virtual std::shared_ptr<base_op> get_op_shared_ptr() { // use shared_from_this, create a base_op object using it. } }; class derived_info : public base_info { virtual std::shared_ptr<base_op> get_op_shared_ptr() { // use shared_from_this + std::*_pointer_cast, // create a derived_op object } }; 

but the point is to avoid run-time polymorphism, since everything can be known by design when creating an instance. Therefore, returning to the beginning of the post, it would be nice to have something like this:

 template<class Op> class base_info { }; class derived_info : public base_info<derived_op> { }; 

with a thingy CRTP type (albeit without output), where op says that it contains objects that create information of this type. But now this causes a cyclical problem for the base_op instance. It must somehow be created by some type of information, which itself is created by an instance of its type, etc. Etc. I do not know how to stop this type of cycle.

Edit

Following the suggestion of Panta rhei, here is the code I was aiming for.

+6
source share
1 answer

I'm still not quite sure what you are trying to achieve, but all you need to do to compile your code is to add a type argument to the template of the base_info class when you create it basically.

 int main() { derived_op d; base_op<base_info<derived_info> > b; } 
+3
source

Source: https://habr.com/ru/post/986869/


All Articles