【问题标题】:Passing a unique_ptr reference to boost::bind?将 unique_ptr 引用传递给 boost::bind?
【发布时间】:2015-05-03 11:03:03
【问题描述】:

我在 CentOS 6.6 (gcc 4.4.7) 上使用 Boost.Asio (1.41) 进行开发。我希望 io_service 在启动时调用管理器对象m 中的成员函数run()。我试图编译的代码如下:

#include <memory>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

boost::asio::io_service io;
std::unique_ptr<manager> m;
m = std::make_unique<manager>;
io.post(boost::bind(&manager::run, &m));

gcc 对boost::bind 声明进行了调整,其中包括:

/usr/include/boost/bind/mem_fn_template.hpp:40: error: pointer to
member type ‘void (manager::)()’ incompatible with object type
‘std::unique_ptr<manager, std::default_delete<manager> >’

我想在这里做什么?

管理器对象只知道定时器;一个知道 io_service 的单独对象稍后将被添加到其构造函数中。但想法是manager::run() 将创建一组初始计时器来引导系统。

澄清:

我的想法是外部代码块管理m 的生命周期,下一条语句将是io.run()。当io.run() 返回时,外部代码将破坏m。因此,将m 的原始引用传递给io 是合适的。但我是一个现代 C++ 新手,在这里可能有点离谱。

【问题讨论】:

  • 您不会将任何类型的引用传递给bind - 您将常规指针传递给唯一指针。但是唯一指针必须是唯一的,并且在您的代码中,当post 返回时,有两个——一个在发布的bind 中,一个在m 中。这显然是不对的。也许你想要boost::bind (&amp;manager::run, std::move(m))
  • boost::bind 不知道如何解开 unique_ptr,您需要将其传递给 manager * (m.get()) 或 manager 实例 (*m)(第二个复制对象m 指向)。而且我很难相信您使用的是 gcc4.4.7;那个编译器甚至不理解-std=c++11,更不用说std::make_unique,C++14 的补充。
  • gcc 4.4.7 有-std=gnu++0x,对于make_unique,我抓住了STL's suggestion

标签: c++ gcc boost boost-asio boost-bind


【解决方案1】:

您需要 C++-14 和 generalized lambda capture 才能完成这项工作——您需要将唯一指针移动到 lambda 中。相反,只需使用 shared_ptrstd::bind 本身就可以理解:

std::shared_ptr<manager> m;
m = std::make_shared<manager>();
io.post(std::bind(&manager::run, std::move(m)));

std::move 是可选的,但可确保 m 在不需要时不会让经理留在身边。

【讨论】:

  • 我觉得这样做很脏,至少就我目前对唯一指针与共享指针的含义的理解而言。 io 不对m 的生命周期负责。按照程序的运行方式,m 将在io.run()(将在io.post() 之后不久)返回后被清理。 make_shared() 会给读者带来错误的想法吗?
  • @AndreasYankopolus m 变量将被清理,但 bind 将按值捕获共享指针,只要 bind 存在,它就必须保留管理器直到执行完成。
  • m 保留为unique_ptr 并将绑定语句更改为:boost::bind(&amp;manager::run, m.get()) 是不是很糟糕?
  • @AndreasYankopolus 是的,因为这样可以过早地删除经理(一旦m 超出范围)。您需要bind 来保持经理的活力,这需要它按价值捕获一些东西,让经理留在身边。
猜你喜欢
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 2012-03-30
  • 2016-03-18
  • 1970-01-01
  • 2014-11-12
相关资源
最近更新 更多