我试图将迭代器返回到过滤范围中的最大元素。以下是我到目前为止的情况:
#include <boost/lambda/lambda.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <vector>
#include <iostream>
using namespace boost::adaptors;
using namespace boost::lambda;
using namespace std;
int main ()
{
vector<double> x = {100, 150, 200, 110};
auto it = boost::max_element(x | indexed(0) | filtered(_1>100)); /* problem here */
cout << it.index() << endl;
return 0;
}
我希望代码打印出矢量x中具有最大元素(即2)的索引,但遗憾的是它不能编译(Linux 64bit,GCC 4.7.2),问题出现在上面指出的行中。我从编译器(以及其他)获得的第一个编译错误如下:
/boost/tuple/detail/tuple_basic.hpp:396:36:错误:只读成员'boost :: tuples :: cons :: head'的分配
任何想法我做错了什么?或者我怎么能实现我想做的事情呢?提前谢谢!
编辑:
将有问题的行更改为:
auto it = boost::max_element<boost::return_found>(x | sliced(1,4) | filtered(boost::function<bool(double)>(_1>100)));
似乎将迭代器返回到最大元素。但是,有没有办法检查迭代器是否在范围内?将它与boost :: end(x)进行比较会给我一个错误。我唯一能想到的就是返回
auto another_range = boost::max_element<boost::return_found_end>(x | sliced(1,4) | filtered(boost::function<bool(double)>(_1>100)));
并检查boost :: empty(another_range)。这是唯一的选择吗?感谢。
答案 0 :(得分:4)
您遇到的具体错误是因为boost lambdas不是CopyAssignable。这是实现相同信息的更简单方法:
auto f1 = _1 > 100;
auto f2 = f1;
f2 = f1; // same error
如果你向filtered
提供一个CopyAssignable仿函数,boost.phoenix(无论如何你应该使用它,boost.lambda正在弃用而不是凤凰),一个手写的结构,或者老忠实std::bind2nd(std::greater<double>(), 100)
,这一行用clang ++编译:
bind2nd demo:http://liveworkspace.org/code/2xKZIf
凤凰演示:http://liveworkspace.org/code/18425g
由于某些boost.concept检查而导致gcc失败,这可能是一个bug,但这是一个没有实际意义的点,因为filtered
的结果是boost::filtered_range
,其迭代器没有.index()
{1}}成员函数。
编辑回应评论:
将迭代器与filtered_range进行比较,将迭代器与原始向量进行比较是行不通的。但是,由于您使用了向量,并且因为它仍然可以访问,因此您可以比较地址,因为indexed
和filtered
都不会复制
#include <vector>
#include <iostream>
#include <cassert>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
using namespace boost::adaptors;
using namespace boost::phoenix::placeholders;
int main ()
{
std::vector<double> x = {100, 150, 200, 110};
auto it = boost::max_element( x | indexed(0) | filtered(arg1 < 110) );
assert(&x[0] <= &*it && &*it < &x[0] + x.size());
std::cout << "Element " << *it << " is at index " << &*it - &x[0] << '\n';
}
demo http://liveworkspace.org/code/1zBIJ9
或者,对于更通用的解决方案,您可以将矢量转换为对矢量(当boost获取zip适配器时,可以使用counting_range整齐地压缩),并将原始序列索引与值一起传递到所有变换。