Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.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++ std::for_不取消迭代器引用的每个等价项_C++_Foreach_Iterator - Fatal编程技术网

C++ std::for_不取消迭代器引用的每个等价项

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::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(),
[](国际一)
{
//如何获取此元素的迭代器???
}
我在寻找什么

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