c++ - boost::bind() 创建参数的许多拷贝

标签 c++ c++11 boost

我正在使用 boost::bind (Boost 1.64.0 和 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 会复制这么多次?
  • 将右值作为参数传递给绑定(bind)是否正确(在两种实现情况下)?
  • 我是否理解正确,bind 会将对象移动到其上下文并存储它,并且当调用 foo 时,将其作为左值引用传递?

谢谢!

最佳答案

这是设计使然。

要避免这种情况,请避免复制绑定(bind)适配器并使用ref:

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

  • 为什么 boost 会复制这么多次?

主要是因为您的构造函数无法被省略。将其保留为聚合或普通构造函数,这样就不会发生。

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

是的,bind 按值捕获参数(除非您使用显式 ref()cref() 来创建 reference_wrapper。)

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

Yes


演示

<强> Live On Coliru

#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

关于c++ - boost::bind() 创建参数的许多拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61409565/

相关文章:

c++ - 虚函数上下文中的支配是什么?

c++ - 从 Boost 多索引迭代器获取数字索引

c++ - Boost::geometry 查询返回索引

c++ - "Heap Corruption Detected"将指针传递给函数然后在指针上调用 free()

c++ - 带引用计数的无锁堆栈

C++11 自日期以来的天数

c++ - Boost - 使用时间戳格式化亚秒精度时间

c++ - 应用程序无法使用 CreateWindowStation 创建 Windows 站

c++ - 404更新文件请求结果

c++ - 无法理解 cv2::absdiff 的行为:c++