如何将谓词传递给算法
how to pass a predicate to algorithm
我有一个问题使用lambda传递谓词,我试图移动与谓词匹配的元素到第二个容器的开始,但它似乎没有工作,所以有什么问题吗?
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <utility>
#include <algorithm>
using namespace std;
template <typename iterator, typename Container, typename T>
void move_if(iterator b, iterator e, Container o, T pred)
{
if(pred)
{
o.insert(o.begin(),pred);
}
}
int main()
{
vector<int>v{1,2,3,4,5,6,7,8,9,10};
vector<int>v2;
for (auto i=v.begin(); i !=v.end(); ++i)
save_if(v.begin(), v.end(), v2, []( vector<int>::iterator i){return (*i>5);});
return 0;
}
试试这个…
int main()
{
std::vector<int> v{1,2,3,4,5,6,7,8,9,10};
std::vector<int> v2;
std::vector<int>::const_iterator
it = std::remove_copy_if(v.begin(), v.end(),
std::back_inserter(v2),
[](int const& i){return i <= 5;});
v.erase(it, v.end);
return 0;
}
您可以在cppreference.com上阅读更多关于remove_copy_if
的信息;它从输入范围中删除元素,并将它们复制到输出中,除非谓词返回true。
看看这个,我对你的代码做了一些修改:
template <typename iterator, typename Container, typename T>
void move_if(iterator a, iterator b, Container &o, T pred)
{
for (auto i = a; i != b; i++)
{
if (pred(*i))
o.insert(o.begin(), *i);
}
}
int main()
{
vector<int>v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int>v2;
move_if(v.begin(), v.end(), v2, [](int i) { return !(i > 5); });
}
注意:如注释所述,如果功能与上述代码相同,建议将move_if
重命名为copy_if
,否则您应该真正移动项目
没有将谓词作为第二个参数的std::vector::insert重载,所以这一行是错误的:
o.insert(o.begin(),pred);
此外,谓词需要带参数
调用。pred(someArg);
在您的情况下将是std::vector<int>::iterator
。另外,save_if
和move_if
也不一样。但更重要的是,它根本不清楚你想要达到什么目标。
在c++ 11中,像[](){return true}
这样不捕获任何东西的无状态lambda可以隐式地转换为函数指针。当您执行if(pred)
时,您将无状态lambda转换为函数指针,检查该指针是否为非空(它是非空的)。这不是你想要做的。
这是move
的实现,b
和e
之间的东西,pred(x)
说应该移动:
template <typename iterator, typename Container, typename T>
void move_if(iterator b, iterator e, Container o, T pred)
{
for( auto i = b; i != e;++i) {
if(pred) {
o.insert(o.end(),std::move(*i));
}
}
}
请注意,我插入在o.end()
,因为你想要的Container
可能是vector
,插入在vector
的end()
要快得多。
实际上,您可能希望使用一个输出迭代器(默认情况下,从Container
使用std::back_inserter
)并将数据输出到该迭代器。类似地,remove_move_if
将是一个更好的删除方式,将元素从b
到e
的范围内打乱,并返回一个iterator
。
最后,基于范围的算法值得编写。不接受begin/end迭代器对,而是接受一个单独的对象,其上的begin(c)
和end(c)
已经被覆盖以返回begin/end。如果您正在处理子范围,则可以传入迭代器struct
的开始/结束范围,并适当地覆盖开始/结束范围。
- std::condition_variable::wait()如何评估给定的谓词
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 为 C++11 算法组合多个谓词
- 如何在算法中使用谓词函数find_if?
- 什么 STL 算法可以确定容器中的一个项目是否满足谓词?
- 为什么指向非静态成员函数的指针不能用作标准库算法的一元谓词
- 是否允许标准库算法复制谓词参数
- 为什么要区分泛型算法的谓词和非谓词版本
- 如何从传递给STL算法的谓词中获取元素的索引
- 使用带有绑定的boost字符串算法谓词
- std::list指针上排序算法的STL谓词
- 为什么序列运算算法谓词是通过复制传递的
- 在c++中通过引用传递std算法谓词
- STL算法的谓词
- 如何将谓词传递给算法