我可以在 C++ Actor Framework 中使用 C++11 智能指针作为消息 return 类型吗?
Can I use C++11 smart pointers as a message return type in the C++ Actor Framework?
当我使用 unique_ptr 作为 return 类型时,我收到编译器错误 C2280:
'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
下面是一些说明该问题的示例代码(根据 C++ Actor 框架示例之一修改):
#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);
}
);
}
是的,C++ Actor Framework 允许在 return 消息中使用智能指针,但不允许以 unique_ptr
.
的形式
C++ Actor Framework 实现当前复制消息并取消引用 unique_ptr
,导致编译器错误。
不使用 unique_ptr
,而是使用 shared_ptr
。修改问题的示例代码时,引用计数将为 2。我还使用自定义删除函数来验证内存是否按预期释放,尽管创建了第二个 share_ptr
.
CAF 要求消息中的每种类型都是常规。这意味着它必须提供一个复制构造函数,std::unique_ptr
没有。因此编译器会报错。
消息具有写时复制的实现。您可以廉价地复制一条消息,因为它只会在内部增加引用计数。您可以随时对消息元素执行常量访问。只有当消息的引用计数大于 1 并且 您请求非常量访问时,写时复制的 "write" 部分才会启动。此时运行时调用包含类型的复制构造函数来创建新消息。
如果 CAF 无条件地执行此复制,独立于引用计数,那么就不可能有效地支持数据流编程,其中参与者接收消息、修改其内容并转发到下一阶段.
将消息视为指针容器:包含的元素在空闲存储中分配。在消息中存储指针通常是一个设计缺陷。双重包装也不必要地强调了分配器。
由于您可以灵活地分割消息,因此您无需创建单个消息,然后可以在各种上下文中使用包含的值。
当我使用 unique_ptr 作为 return 类型时,我收到编译器错误 C2280:
'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
下面是一些说明该问题的示例代码(根据 C++ Actor 框架示例之一修改):
#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);
}
);
}
是的,C++ Actor Framework 允许在 return 消息中使用智能指针,但不允许以 unique_ptr
.
C++ Actor Framework 实现当前复制消息并取消引用 unique_ptr
,导致编译器错误。
不使用 unique_ptr
,而是使用 shared_ptr
。修改问题的示例代码时,引用计数将为 2。我还使用自定义删除函数来验证内存是否按预期释放,尽管创建了第二个 share_ptr
.
CAF 要求消息中的每种类型都是常规。这意味着它必须提供一个复制构造函数,std::unique_ptr
没有。因此编译器会报错。
消息具有写时复制的实现。您可以廉价地复制一条消息,因为它只会在内部增加引用计数。您可以随时对消息元素执行常量访问。只有当消息的引用计数大于 1 并且 您请求非常量访问时,写时复制的 "write" 部分才会启动。此时运行时调用包含类型的复制构造函数来创建新消息。
如果 CAF 无条件地执行此复制,独立于引用计数,那么就不可能有效地支持数据流编程,其中参与者接收消息、修改其内容并转发到下一阶段.
将消息视为指针容器:包含的元素在空闲存储中分配。在消息中存储指针通常是一个设计缺陷。双重包装也不必要地强调了分配器。
由于您可以灵活地分割消息,因此您无需创建单个消息,然后可以在各种上下文中使用包含的值。