【问题标题】:How to use boost::bind with non-copyable params, for example boost::promise?如何将 boost::bind 与不可复制的参数一起使用,例如 boost::promise?
【发布时间】:2011-02-19 14:58:18
【问题描述】:

一些 C++ 对象没有复制构造函数,但有移动构造函数。 例如,boost::promise。 如何使用它们的移动构造函数绑定这些对象?

#include <boost/thread.hpp>

void fullfil_1(boost::promise<int>& prom, int x)
{
  prom.set_value(x);
}

boost::function<void()> get_functor() 
{
  // boost::promise is not copyable, but movable
  boost::promise<int> pi;

  // compilation error
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, pi, 1);

  // compilation error as well
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, std::move(pi), 1);

  // PS. I know, it is possible to bind a pointer to the object instead of 
  // the object  itself. But it is weird solution, in this case I will have
  // to take cake about lifetime of the object instead of delegating that to
  // boost::bind (by moving object into boost::function object)
  //
  // weird: pi will be destroyed on leaving the scope
  boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(pi), 1);
  return f_set_one;
}

【问题讨论】:

  • 使用指针并不奇怪,这取决于您将绑定对象提供给什么。例如,如果您使用信号,则可以保存 Connection 对象,并在对象的 dtor 中调用 disconnect。如果你不使用信号,你可以开发类似的东西,或者将指针包装在 shared_ptr 中。
  • boost::promise 实际上是一个 shared_ptr 和一个 bool。它应该在堆上分配并使用另外一个 shared_ptr 进行跟踪,这似乎很奇怪。

标签: c++ boost-thread boost-bind boost-function


【解决方案1】:

我不确定如何改用移动构造函数,但另一种方法是使用 boost::ref 创建对对象的可复制引用,然后您可以将它们传递给 boost::bind。

【讨论】:

  • boost::ref 仅在引用的对象存活时才起作用?
  • 是的,因此您需要担心正在使用的对象的寿命。
【解决方案2】:

我看到你使用 std::move。为什么不使用应该知道移动语义的 std::bind ?

template<class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);
template<class R, class F, class... BoundArgs>
unspecified bind(F&&, BoundArgs&&...);

关于声明 fullfil_1 的移动版本的内容

void fullfil_1(boost::promise<int>&é prom, int x)
{
  prom.set_value(x);
}

Boost.Bind 还不支持移动语义(至少我不知道)。希望目前审核的 Boost.Move 能被接受,并且 Boost.Bind、Boost.Lambda 和 Boost.Phoenix 会添加移动语义接口。

您可以尝试编写 ref 并按如下方式移动

boost::function<void()> f_set_one = boost::bind(&fullfil_1, boost::ref(std::move(pi)), 1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多