C++ std::for_不取消迭代器引用的每个等价项
是否有像std::for_each这样的函数直接传递迭代器而不是解引用迭代器的结果 我们所拥有的C++ std::for_不取消迭代器引用的每个等价项,c++,foreach,iterator,C++,Foreach,Iterator,是否有像std::for_each这样的函数直接传递迭代器而不是解引用迭代器的结果 我们所拥有的 std::vector<int> ints; std::for_each(ints.begin(), ints.end(), [](int i) { //how to get the iterator of this element??? } std::vector ints; std::for_each(ints.begin()、ints.end(), [](国际一) { //如
std::vector<int> ints;
std::for_each(ints.begin(), ints.end(),
[](int i)
{
//how to get the iterator of this element???
}
std::vector ints;
std::for_each(ints.begin()、ints.end(),
[](国际一)
{
//如何获取此元素的迭代器???
}
我在寻找什么
for_each_iterator(ints.begin(), ints.end(),
[](const std::vector<int>::const_iterator &i)
{
//we know the iterator here
}
对于每个迭代器(ints.begin()、ints.end(),
[](常量std::vector::常量迭代器&i)
{
//我们知道这里的迭代器
}
当然,编写这样一个函数是相当简单的,但我想问的是,是否存在来自
std:
、std::tr1:
或boost:
的标准解决方案,您看到的抽象级别是错误的nge。如果需要对迭代器进行操作,则应展开循环:
for (auto it = ints.begin(); it != ints.end(); ++it ) {
// do something
}
您所要求的将是可实现的,只是在我看来没有那么有用或者迭代器本身没有什么用处。您想从迭代器中得到什么?标准库中没有这样的东西。但自己实现它并不难:
template<typename It, typename Functor >
void iterate(It begin, It end, Functor && f)
{
while ( begin != end ) { f(begin); ++begin; }
}
模板
无效迭代(它开始、结束、函子(&f)
{
while(begin!=end){f(begin);++begin;}
}
并将其用作:
iterate(ints.begin(), ints.end(), [](std::vector<int>::iterator it)
{
//use it
});
迭代(ints.begin()、ints.end()、[](std::vector::iterator)
{
//使用它
});
或者使用手动循环。我只能想到如何使用迭代器的包装器,我想不出一种只使用标准算法的方法,所以您仍然需要编写一些辅助代码。例如:
#include <algorithm>
#include <vector>
#include <iostream>
template<typename T>
struct it_wrapper {
it_wrapper(const T& t) : it(t) { }
T operator*() const {
return it;
}
it_wrapper& operator++() {
++it;
return *this;
}
it_wrapper operator++(int) {
it_wrapper old = *this;
++it;
return old;
}
bool operator!=(const it_wrapper& rhs) {
return it != rhs.it;
}
T it;
};
template<typename T>
it_wrapper<T> wrap(const T& t) {
return it_wrapper<T>(t);
}
int main() {
std::vector<int> v { 1, 2, 3, 4 };
std::for_each(wrap(v.begin()), wrap(v.end()), [](decltype(v.begin()) i) {
std::cout << *i << '\n';
});
}
#包括
#包括
#包括
模板
结构it_包装器{
it_包装器(const T&T):it(T){
T运算符*()常数{
归还它;
}
it_包装器和运算符++(){
++它;
归还*这个;
}
it_包装运算符++(int){
it_wrapper old=*这个;
++它;
返老还童;
}
布尔运算符!=(常量it_包装和rhs){
返回它!=rhs.it;
}
不是吗;
};
模板
it_包装包装(const T&T){
退回包装纸(t);
}
int main(){
std::向量v{1,2,3,4};
std::for_each(wrap(v.begin())、wrap(v.end())、[](decltype(v.begin())i){
std::cout你会用它做什么?我曾多次遇到过这个问题。目前我正在尝试将两个迭代器压缩在一起,以比较它们表示的范围(而不是它们指向的值)。这是为了单元测试目的。除非迭代器本身就是元素,“在迭代器上迭代”的想法听起来有点自相矛盾。你想验证范围是否相同吗?对两个序列中的开始/结束迭代器进行简单的直接比较将告诉你它们是否相同。也就是说,给定相同的开始和结束,所有迭代器(以及它们引用的元素)中间是相同的。也就是说,如果你想测试等式,你想测试这些值,而迭代器也没有帮助,如果你想测试身份,你只需要测试原始迭代器,就不需要验证序列中的每一个元素。@ DavidRodr·Guez Dr.Neasas:你是对的。我忘了两者都指向相同的结构。所以我想我必须检查范围的每一个元素。你只是重新表述了他的意思question@qdii当前位置最后一部分可能是,但第一句话是正确的,不在问题中:他在看错误的抽象层次。嗯……函子应该被普遍引用。除此之外,我看不出有什么好的用途函数的例子:)@DavidRodríguez dribeas:我编辑了它。但我不知道为什么通过普遍引用接受它更好?它有什么区别吗?不仅仅是避免复制(它不会),但您可以传递有状态对象,它将就地更新对象。请注意,这与标准中的std::for_each
的行为不同,但也更灵活。@DavidRodríguez dribeas:不一定更灵活,因为您无法按值传递函子。使用for_each()
,您可以使用ref(f)
通过reference@Nawaz:我想这取决于……有状态函子的问题(使用标准算法)保证通常不足以正确管理状态,例如,标准按值获取函子,并允许内部复制。例如,remove\u if
的常见实现首先调用find\u if
(创建函子副本)然后从那里继续,这意味着在第一次命中之前,将使用一个谓词,在第一次命中之后使用另一个谓词。我也考虑过这一点。是否有一个标准的解决方案(如我的问题中所述)对于这个indirector?@据我所知,没有人不知道,除非你想用迭代器填充一个向量并在该向量上迭代,这将是一种浪费。这是一种智力练习,还是你真的不喜欢为
-循环编写类和?如果我必须选择,那么我会说后者。去年我意识到了这一点我的代码中有2/3已经作为标准解决方案存在,所以我现在尽量避免这种情况。@Nobody是的,这是一种很好的心态。但我很确定所有标准算法都会给您提供范围内的元素,而不是迭代器,因为卑微的for
已经在一行中提供了该功能:for(自动i=v.begin();i!=v.end();++i)工作(i);