Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 过滤范围、lambdas和已排序_C++_C++11_Lambda_Boost Range - Fatal编程技术网

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; });