C++ 过滤范围、lambdas和已排序
这是过滤迭代器问题的简化版本(因此,要求我以不同方式重写它以避免过滤是没有意义的)。奇怪的是,在真正的代码中,只有C++ 过滤范围、lambdas和已排序,c++,c++11,lambda,boost-range,C++,C++11,Lambda,Boost Range,这是过滤迭代器问题的简化版本(因此,要求我以不同方式重写它以避免过滤是没有意义的)。奇怪的是,在真正的代码中,只有被排序似乎是问题所在,其他的用法似乎可以正常工作 #include <vector> #include <boost/range/adaptor/filtered.hpp> #include <boost/range/algorithm_ext/is_sorted.hpp> int main(int argc, const char* argv[
被排序
似乎是问题所在,其他的用法似乎可以正常工作
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm_ext/is_sorted.hpp>
int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
std::vector<int> all = {1,2,3,4,5,6,7,8,9};
auto some = all | filtered([] (int i) { return i % 2; });
return boost::is_sorted(some);
}
#包括
#包括
#包括
int main(int argc,const char*argv[]
{
使用名称空间boost::适配器;
向量all={1,2,3,4,5,6,7,8,9};
auto some=all | filtered([](int i){返回i%2;});
返回提升::已排序(部分);
}
这无法使用Clang++3.5和G++4.9(在Mac OS X上,最新版本)编译:
$clang++-mp-3.5-std=c++11-isystem/opt/local/include/foo.cc
在foo.cc中包含的文件中:3:
在/opt/local/include/boost/range/algorithm_ext/is_sorted包含的文件中。hpp:18:
/opt/local/include/boost/detail/已排序。hpp:25:28:错误:类型为的对象
无法分配“boost::filter_iterator”,因为其复制分配运算符为
隐式删除
for(;it!=最后;first=it,++it)
^
...
/opt/local/include/boost/iterator/filter\u iterator.hpp:106:17:注意:复制
“filter_iterator”的赋值运算符被隐式删除,因为字段
“m_谓词”有一个已删除的复制赋值运算符
谓词m_谓词;
^
foo.cc:9:30:注意:lambda表达式从这里开始
auto some=all | filtered([](int i){返回i%2;});
^
我知道将lambda存储在std::function
中可以修复它,但我想避免付费
它的价格。在std::is_sorted
周围使用自定义包装器并不能解决此问题。此问题似乎与其他问题有关(例如),
但事实并非如此——至少他们的疗法在这里并不适用
谢谢 内部
已排序
复制用于对序列进行迭代的迭代器,以便可以使用它来比较相邻元素。这意味着,过滤的
(即lambda)的谓词也需要复制,即使它从未实际用于递增尾部迭代器。复制迭代器的其他算法也会有同样的问题,例如相邻的\u-find
复制迭代器的算法与不复制迭代器的算法的区别在于前者被称为“多路径”算法,需要迭代器类型来满足,而后者是单过程的,只需要inputierator
解决方案是为lambda局部作用域提供生存期,并将其传递给:
另一种选择是:
不过,这只适用于无捕获功能的lambdas,可能还不清楚。你能解释一下前面的“+”是怎么回事吗?@ThomasB。太好了,非常感谢!谢谢你的回答!不过,我不明白为何其他用途没有这问题。例如,
For(auto i:some)
而不是(some)
是有效的。这甚至没有任何编译器优化(在这种情况下,我会理解所有内容都被展开、内联等,这导致根本没有lambda,因此没有问题)。如果在这种情况下,编译器确实能够内联,为什么不使用像is_sorted
这样简单的方法呢?@akim啊,我错了-is_sorted
是一种多路径算法,因此需要前向迭代器。谢谢,我已经更新了我的答案。
$ clang++-mp-3.5 -std=c++11 -isystem /opt/local/include/ foo.cc
In file included from foo.cc:3:
In file included from /opt/local/include/boost/range/algorithm_ext/is_sorted.hpp:18:
/opt/local/include/boost/detail/is_sorted.hpp:25:28: error: object of type
'boost::filter_iterator<(lambda at foo.cc:9:30), std::__1::__wrap_iter<int
*> >' cannot be assigned because its copy assignment operator is
implicitly deleted
for (; it != last; first = it, ++it)
^
...
/opt/local/include/boost/iterator/filter_iterator.hpp:106:17: note: copy
assignment operator of 'filter_iterator<(lambda at foo.cc:9:30),
std::__1::__wrap_iter<int *> >' is implicitly deleted because field
'm_predicate' has a deleted copy assignment operator
Predicate m_predicate;
^
foo.cc:9:30: note: lambda expression begins here
auto some = all | filtered([] (int i) { return i % 2; });
^
auto odd = [] (int i) { return i % 2; };
auto some = all | filtered(std::ref(odd));
auto some = all | filtered(+[] (int i) { return i % 2; });