我试图在lower_bound
的转换迭代器上调用vector<unique_ptr>>.
。之前已经在SO上提出了类似的问题。这个问题稍微复杂一些,因此其他问题的解决方案并不适用。
问题是一样的。 std实现在搜索期间将__first
分配给__middle
时调用unique_ptr operator =。在此示例中,搜索变换对象列表(int-&gt; double)以定位等于或大于输入(double)的元素。
int main ()
{
vector<unique_ptr<int>>v {
std::make_unique<int>(0),
std::make_unique<int>(1),
std::make_unique<int>(2),
std::make_unique<int>(3),
std::make_unique<int>(4),
};
auto transFunc = [](const unique_ptr<int>& m) -> double {
return (*m) * 2.;
};
auto first = boost::make_transform_iterator(begin(v), transFunc);
auto last = boost::make_transform_iterator(end(v), transFunc);
auto i = lower_bound(first, last, 5.);
return 0;
}
我也尝试过使用move_iterator。
auto transFunc = [](unique_ptr<int>&& m) -> double {
return (*m) * 2.;
};
auto first = boost::make_transform_iterator(
make_move_iterator(begin(v)), transFunc);
auto last = boost::make_transform_iterator(
make_move_iterator(end(v)), transFunc);
似乎boost在转换后的迭代器中没有带来正确的价值。
用于在VS2013中工作但在VS2015或GNU中不起作用的代码。
答案 0 :(得分:1)
lambda不可复制,默认情况下transform_iterator
会保留可调用的副本。
简单解决方案:std::ref
或std::cref
:
<强> Live On Coliru 强>
#include <memory>
#include <boost/iterator/transform_iterator.hpp>
#include <vector>
int main ()
{
auto transFunc = [](const std::unique_ptr<int>& m) -> double { return (*m) * 2; };
std::vector<std::unique_ptr<int>> v;
v.push_back(std::make_unique<int>(0));
v.push_back(std::make_unique<int>(1));
v.push_back(std::make_unique<int>(2));
v.push_back(std::make_unique<int>(3));
v.push_back(std::make_unique<int>(4));
auto first = boost::make_transform_iterator(begin(v), std::cref(transFunc));
auto last = boost::make_transform_iterator(end(v), std::cref(transFunc));
auto i = lower_bound(first, last, 5.);
}
创建一个可复制的calleable:
struct { double operator()(const std::unique_ptr<int>& m) const { return (*m) * 2; }; } transFunc;
<强> Live On Coliru 强>
<强> Live On Coliru 强>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
#include <vector>
#include <memory>
using namespace boost::adaptors;
using namespace boost::phoenix::arg_names;
int main () {
std::vector<std::unique_ptr<int>> v(5);
boost::generate(v, [n=0]() mutable { return std::make_unique<int>(n++); });
auto i = boost::lower_bound(
v |
indirected |
transformed(2. * arg1), 5.);
}