Can I use C ++ 11 smart pointers as a return type in a C ++ Actor Framework?

When I use unique_ptr as the return type, I get a C2280 compiler error:

'caf::detail::tuple_vals<std::unique_ptr<A,std::default_delete<_Ty>>>::tuple_vals(const caf::detail::tuple_vals<std::unique_ptr<_Ty,std::default_delete<_Ty>>> &)': attempting to reference a deleted function include\caf\detail\tuple_vals.hpp 102 

Here is a sample code that illustrates the problem (modified from one of the C ++ Actor Framework examples):

 #include <iostream> #include "caf/all.hpp" using namespace caf; using namespace std; class A { public: int a; A(int a) { this->a = a; } }; using a_type = typed_actor<replies_to<int>::with<unique_ptr<A>>>; a_type::behavior_type a_behavior(a_type::pointer self) { return { [self](const int& a) -> unique_ptr<A> { return make_unique<A>(5); } }; } void tester(event_based_actor* self, const a_type& testee) { self->link_to(testee); // will be invoked if we receive an unexpected response message self->on_sync_failure( [=] { aout(self) << "AUT (actor under test) failed" << endl; self->quit(exit_reason::user_shutdown); }); self->sync_send(testee, 5).then( [=](unique_ptr<A> a) { if(a->a == 5) { aout(self) << "AUT success" << endl; } self->send_exit(testee, exit_reason::user_shutdown); } ); } 
+5
source share
2 answers

CAF requires that each message type be regular. This means that it must provide a copy constructor that std::unique_ptr does not have. Therefore, the compiler complains.

Messages have an implementation of copy to write. You can copy one message cheaply, as it just hits the link counter inside. At any time, you can const-access message elements. The "write" part of the copy-to-write part only works if the link count is greater than 1 and you are requesting non-constant access. At this point, the runtime invokes the copy constructor of the contained type to create a new message.

If the CAF unconditionally executes this copy, regardless of the reference count, then it would be impossible to effectively support the programming of the data stream when the actor receives the message, changes its contents and proceeds to the next step.

Think of messages as containers of pointers: contained elements are allocated in free storage. Storing a pointer in a message is usually a design flaw. Double packaging also requires excessive distribution of the dispenser.

Since you can flexibly crop messages, you do not need to create a single message and then use the contained value in different contexts.

+4
source

Yes, the C ++ Actor Framework allows smart pointers in return messages, but not in the form of unique_ptr .

The C ++ implementation of the Actor Framework currently makes a copy of the message and unique_ptr , causing a compiler error.

Instead of using unique_ptr , use shared_ptr instead. The reference count will be 2 when changing the code of the sample question. I also used a custom delete function to make sure the memory was released as expected, despite creating a second share_ptr .

+2
source

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


All Articles