使用boost :: transform_iterator用非const函子(Use boost::

2019-09-23 20:59发布

我想用一个transform_iterator使在一系列的增量转型。 由增量变换我的意思是,R 0应该保持相同和随后的元素,RⅠ,被映射到(R I - R I - 1)。

我的问题是,据我可以告诉transform_iterator需要一个const函子,但我的仿函数需要记住以前的值。 我该如何解决这个问题? 如果我只是写我自己的迭代器?

我想把它当作一个迭代的原因是,在下一步我想通过它进行了一系列的适配器。

编辑:看来transform_iterator确实允许非const函子,它真的是我的范围适配器,抱怨缺乏常量性。 我会继续的问题,因为它是如何适当使用transform_iterator反正看起来有趣的讨论开放。

Answer 1:

我不认为你可以完全正确地有这个工作,提升:: transform_iterator。 这是一个简单的实现,这似乎像它可能在第一个工作,但并没有真正很好地工作:

#include <boost/iterator/transform_iterator.hpp>
#include <vector>
#include <iostream>

using std::cout;

struct Delta {
  Delta() : prev_value(0) { }

  int operator()(int value) const
  {
    int result = value-prev_value;
    prev_value = value;
    return result;
  }

  mutable int prev_value;
};

int main(int,char**)
{
  typedef std::vector<int> Items;
  typedef boost::transform_iterator<Delta,Items::iterator,int> Iter;

  Items items;
  items.push_back(4);
  items.push_back(3);
  items.push_back(8);
  { // prints 4 -1 5  -- excellent
    Iter i(items.begin(),Delta()), end(items.end(),Delta());
    for (;i!=end;++i) {
      cout << *i << " ";
    }
    cout << "\n";
  } 
  { // prints 4 0 -- crap
    Iter i(items.begin(),Delta());
    cout << *i << " ";
    cout << *i << "\n";
  }
  return 0;
}

要真正使这项工作,你需要知道什么时候该迭代器是先进的,所以我认为你需要你自己的迭代。



Answer 2:

这似乎为我工作得很好,甚至当我使用指针记住以前的值(这可能是也可能不是你的情况是个好主意)。

#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/iterator/transform_iterator.hpp>

class delta {
public:
  typedef int result_type;

  int operator()(const int& i) const {
    if(prev) {
      const int* tmp = prev;
      prev = &i;
      return i - *tmp;
    } else {
      prev = &i;
      return i;
    }
  }
private:
  mutable const int* prev = nullptr;
};

int main()
{
  std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::for_each(boost::make_transform_iterator(begin(v), delta()), 
                boost::make_transform_iterator(end(v), delta()),
                [](int i) { std::cout << i << std::endl; });

  return 0;
}

它不会与拉姆达的工作,虽然,即使你使用decltype,和因为状态拉姆达已被标记可变的,你不能隐藏副作用,你可以用一个可变的成员。



文章来源: Use boost::transform_iterator with a non-const functor
标签: c++ boost