2

我从 C++ 食谱中复制了一些代码来实现跨步迭代器。迭代器似乎适用于其他stl函数,例如copy,但不适用于sort. 我的猜测是,这与缺少一些操作员有关。这是我的跨步迭代器的头文件(来自 Oreilly C++ 食谱)

#define STRIDEITER_HPP

#include <iterator>
#include <cassert>

template<class Iter_T>
class stride_iter
{
public:
  // public typedefs
  typedef typename std::iterator_traits<Iter_T>::value_type value_type;
  typedef typename std::iterator_traits<Iter_T>::reference reference;
  typedef typename std::iterator_traits<Iter_T>::difference_type difference_type;
  typedef typename std::iterator_traits<Iter_T>::pointer pointer;
  typedef std::random_access_iterator_tag iterator_category;
  typedef stride_iter self;

  // constructors
  stride_iter( ) : m(NULL), step(0) { };
  stride_iter(const self& x) : m(x.m), step(x.step) { }
  stride_iter(Iter_T x, difference_type n) : m(x), step(n) { }

  // operators
  self& operator++( ) { m += step; return *this; }
  self operator++(int) { self tmp = *this; m += step; return tmp; }
  self& operator+=(const difference_type x) { m += (x * step); return *this; }
  self& operator--( ) { m -= step; return *this; }
  self operator--(int) { self tmp = *this; m -= step; return tmp; }
  self& operator-=(const difference_type x) { m -= x * step; return *this; }
  reference operator[](const difference_type n) { return m[n * step]; }
  reference operator*( ) { return *m; }

  // friend operators
  friend bool operator==(const self& x, const self& y) {
    assert(x.step == y.step);
    return x.m == y.m;
  }
  friend bool operator!=(const self& x, const self& y) {
    assert(x.step == y.step);
    return x.m != y.m;
  }
  friend bool operator<(const self& x, const self& y) {
    assert(x.step == y.step);
    return x.m < y.m;
  }
  friend difference_type operator-(const self& x, const self& y) {
    assert(x.step == y.step);
    return (x.m - y.m) / x.step;
  }

  friend self operator+(const self& x, difference_type y) {
    assert(x.step == y.step);
    return x += (y * x.step);
  }
  friend self operator+(difference_type x, const self& y) {
    assert(x.step == y.step);
    return y += x * x.step;
  }
private:
  Iter_T m;
  difference_type step;
};
#endif

我打电话正在使用

#include "strideiter.hpp"
#include <algorithm>
#include <iterator>
#include <iostream>

using namespace std;

int main( ) {

  int *a;
  a =(int*) malloc(10*sizeof(int));

  for(int i=0; i<10; i++)
    {
      a[i]=10-i;
    }

  int skip=2;

  stride_iter<int*> first(a+2, skip);
  stride_iter<int*> last(a + 2+8, skip);
  sort(first,last);
}

我收到几个错误,第一个是:

strideiter.hpp(52): error: expression must have class type
  assert(x.step == y.step);

我需要多个实现+=吗?

4

2 回答 2

4

修复operator+并提供一个operator-(self, difference_type),它编译得很好。“RandomAccessIterator概念”并std::sort有大量要求,您可以在另一个涉及迭代器的问题中找到这些要求。

friend self operator+(const self& x, difference_type y) {
  // do not modify `x`, but return a modified copy
  return self(x.m + (y * x.step), x.step);
  // idiomatically:
  // self temp(x);
  // temp += y;
  // return temp;
}
friend self operator+(difference_type x, const self& y) {
  return y+x;
}

friend self operator-(const self& x, difference_type y) {
  return self(x.m - (y * x.step), x.step);
}

对于这种用法:

int main( ) {

  int a[10];
  //a =(int*) malloc(10*sizeof(int));

  for(int i=0; i<10; i++)
    {
      a[i]=10-i;
    }

  for(int e : a) std::cout << e << ", ";
  std::cout << std::endl;

  int skip=2;

  stride_iter<int*> first(a+2, skip);
  stride_iter<int*> last(a + 2+8, skip);
  sort(first,last);

  for(int e : a) std::cout << e << ", ";
  std::cout << std::endl;
}

输出是:

10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
10, 9, 2, 7, 4, 5, 6, 3, 8, 1,

这在我看来是合理的。

于 2013-09-26T17:06:35.563 回答
1

问题是您将迭代器声明为 a random_access_iterator,但您没有提供 operator+andoperator-函数。

话虽如此,你的迭代器是在玩火,因为它只有在容器的大小是步幅的精确倍数时才会起作用。如果您有一个包含 100 个元素的容器,并且您要求步长为 3,那么您将有未定义的行为。为了有用,您的迭代器必须同时获取范围的开始和结束,这样它就可以避免跨过结束(或开始,当向后跨步时)。

于 2013-09-26T17:17:29.950 回答