gpt4 book ai didi

c++ - 将 Boost 适配器与 std::bind 表达式一起使用

转载 作者:行者123 更新时间:2023-11-27 22:58:11 31 4
gpt4 key购买 nike

我有以下代码:

#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm.hpp>

#include <iostream>
#include <functional>
#include <memory>

struct A {
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};

struct B {
B() = default;
B(const B&) = delete;
B& operator=(const B&) = delete;

int foo(const A&, int b) {
return -b;
}
};

int main() {
A a;
auto b = std::make_shared<B>();
std::vector<int> values{1, 2, 3, 2};

using std::placeholders::_1;
auto fun = std::bind(&B::foo, b.get(), std::ref(a), _1);
int min = *boost::min_element(values | boost::adaptors::transformed(fun));
std::cout << min << std::endl;
}

当我尝试编译它时,clang 给出以下错误消息(完整输出 here ):

/usr/local/include/boost/optional/optional.hpp:674:80: error: object of type 'std::_Bind<std::_Mem_fn<int (Base::*)(const A &, int)> (Base *, std::reference_wrapper<A>, std::_Placeholder<1>)>' cannot be assigned because its copy assignment operator is implicitly deleted

似乎虽然绑定(bind)对象有一个复制构造函数,但它的复制赋值运算符被删除了。如果我尝试使用 lambda 而不是 bind,我会得到同样的错误。

  1. 这是 C++11 标准、libstdc++ 实现或 Boost 适配器实现中的错误吗?

  2. 最好的解决方法是什么?我可以将它包装到 std::function 中。 boost::bind 似乎也有效。哪个更有效,或者真的很重要?

最佳答案

问题是:

  1. 标准不要求 std::bind 的返回值是可复制赋值的;仅移动可构造(如果所有绑定(bind)对象也是可复制构造的,则可复制构造)。对于 lambda,需要删除它们的复制赋值运算符。

  2. 范围适配器实际上使用了 transform_iterator,因此函数对象存储在迭代器中。

  3. 迭代器必须是可复制分配的,min_element 试图做到这一点,而您的程序会崩溃。

随着 C++11 中 lambda 的激增,我认为这是 boost 库的问题,它在设计时并未考虑可复制构造但不可复制分配的函数对象。

我实际上建议将生成的函数对象包装在 reference_wrapper 中:

int min = *boost::min_element(values | boost::adaptors::transformed(std::ref(fun)));

这也节省了在复制迭代器时额外复制仿函数的成本。

在您列出的两个选项中,boost::bind 应该更高效,因为它不必进行类型删除。

关于c++ - 将 Boost 适配器与 std::bind 表达式一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30493177/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com