作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试调用 lower_bound
在 vector<unique_ptr>>.
的转换迭代器上之前在 SO 上已经问过类似的问题。这个问题稍微复杂一些,其他问题的解决方案不容易应用。
问题是一样的。 std 实现在分配 __first
时调用 unique_ptr operator=至 __middle
在搜索过程中。在此示例中,搜索转换对象列表 (int->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。
最佳答案
lambda 不可复制,默认情况下 transform_iterator
会保留可调用的拷贝。
简单的解决方案:std::ref
或 std::cref
:
#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.);
}
改为创建一个可复制的可调用对象:
struct { double operator()(const std::unique_ptr<int>& m) const { return (*m) * 2; }; } transFunc;
#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.);
}
关于c++ - 如何在std算法中使用unique_ptr的transform_iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49618374/
我是一名优秀的程序员,十分优秀!