boost::bind()会创建许多参数的副本。

我在使用 boost::bind (Boost 1.64.0 and gcc 8.3.0) 创建一个可调用的对象时,注意到了一个有趣的特性:在 bind 构造函数中传递的对象作为一个可封装函数的参数,会被复制多次,即使该对象被 std::move() 封装。虽然std::bind的工作原理和预期一样。

#include <iostream>
#include <boost/bind.hpp>
#include <functional>

class Test
{
public:
    Test()
    {
        std::cout << "Create\n";
    }

    Test(const Test& rhs)
    {
        std::cout << "Copy\n";
    }

    Test(Test&& rhs)
    {
        std::cout << "Move\n";
    }

    ~Test() noexcept
    {

    }
};

void foo(Test& t)
{

}


int main()
{
    Test t;
    auto f = boost::bind(&foo, t);
    f();
}

boost::bind(&foo, t)的输出。

Create
Copy
Copy
Copy
Copy
Copy

boost::bind(&foo, std::move(t))的输出。

Create
Move
Copy
Copy
Copy
Copy

std::bind(&foo, t)的输出。

Create
Copy

std::bind(&foo, std::move(t))的输出。

Create
Move
  • 为什么boost会复制这么多次?
  • 将rvalue作为参数传递给bind是否正确(在两种实现情况下)?
  • 我的理解是否正确,bind会将对象移动到它的上下文中并存储起来,而当foo被调用时,将其作为lvalue引用传递给它?

谢谢你!我是在使用boost::bind来工作的。

解决方案:

这是设计上的。

为了避免这种情况,请避免使用bind适配器的副本,而使用 ref:

auto f = boost::bind(&foo, boost::ref(t));

  • 为什么会提升复制这么多次?

主要是因为你的构造函数不能被省略。保持它是一个集合或琐碎的构造函数,就不会发生这种情况。

  • 将rvalue作为参数传给bind(在两种实现情况下)是否正确?

是的,bind 通过值来捕获参数(除非你使用显式的 ref()cref() 营造 reference_wrappers.)

  • 我的理解是否正确,bind会将对象移动到它的上下文中并将其存储起来,当调用foo时,将其作为lvalue引用传递给它?

是的,我的理解是正确的,当调用foo时,将它作为一个l值引用传递给它?


演示

活在科利鲁

#include <boost/bind.hpp>
#include <functional>
#include <iostream>

struct Test {
    Test()                       { std::cout << "Create\n"; } 
    Test(const Test& /*unused*/) { std::cout << "Copy\n";   } 
    Test(Test&& /*unused*/)      { std::cout << "Move\n";   } 
    ~Test() noexcept             {                          } 
};

void foo(Test& /*unused*/) {}

int main() {
    Test t;
    auto f = boost::bind(&foo, boost::ref(t));
    f();
}

印刷品。

Create

给TA打赏
共{{data.count}}人
人已打赏
未分类

Debezium cassandra CDC插件安装在cassandra节点上。

2022-9-9 5:08:16

未分类

如何在Flutter项目中运行选定的飞镖文件作为主程序?

2022-9-9 5:08:18

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索