首页 > 解决方案 > 我的 C++ 模板类中的 begin() 方法出现问题

问题描述

我的班级的 begin() 方法有问题。该类应该将输入拆分vector<C>为“页面”,即拆分为一个处理类的vector<IteratorRange<vector<C>::iterator>> pages 位置,以便我可以迭代为:IteratorRangebegin()end()

for (auto& page : pages) {
  for (auto& element : page) {
    std::cout << element << " ";
  }
  std::cout << std::endl;
}

这一切似乎都很简单,但几周以来我无法摆脱一个奇怪的错误......如果有人可以帮助解决它,我将不胜感激。最小的实现如下。

#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

template <typename Iterator>
class IteratorRange {
private:    
    Iterator first, last;
public:
    IteratorRange(Iterator f, Iterator l) : first(f), last(l) { }
    Iterator begin() const {
        return first;
    }
    Iterator end() const {
        return last;
    }
    size_t size() const {
      return last - first;
    }
};
// this is a template function that extracts a slice of a Container
template <typename Container>
auto Slice(Container& v, size_t bottom, size_t size) {
    return IteratorRange(
        v.begin()+bottom, next(v.begin()+bottom,min(size,v.size()-bottom))
    );
}

// this is a template function that splits a vector<C> into pages
template <typename C>
auto Paginate(C& c, size_t page_size) {
    vector<IteratorRange<typename C::iterator>> pages;
    int counter = 0;
    do {
        IteratorRange<typename C::iterator> page = Slice(c,counter*page_size,page_size);
        pages.push_back(page);
        ++counter;
    } while (pages.back().end() != c.end()); 
    return pages;
}

template <typename Iterator>
class Paginator {
private:
    vector<IteratorRange<Iterator>> pages;    
public:
    Paginator(Iterator start, Iterator stop, size_t page_size) {
        vector obj(start,stop);
        pages = Paginate(obj,page_size);
        // test
        cout << "Inside the Paginator constructor method: vector split by " << page_size << " elements per page:" << endl;
        int page_nb = 0;
        for (const auto& page : pages) {
            cout << "Page " << ++page_nb << ": ";
            for (const auto& element : page) {
            cout << element << " ";
            }
            cout << endl;
        }      
    } 
    auto begin() const {
      return pages.begin();
    }
    auto end() const {
      return pages.end();
    }
};


int main() {
  vector<int> v(5);
  iota(begin(v), end(v), 1);
  cout << "Initial vector: ";
  for (const auto& element : v) {
      cout << element << " ";
  }
  cout << endl;

  int elem_per_page = 2;
  Paginator<vector<int>::iterator> paginate_v(v.begin(), v.end(), elem_per_page);

  cout << "Vector split by " << elem_per_page << " elements per page:" << endl;
  int page_nb = 0;
  for (const auto& page : paginate_v) {
    cout << "Page " << ++page_nb << ": ";
    for (const auto& element : page) {
      cout << element << " ";
    }
    cout << endl;
  }
}

输出是

Initial vector: 1 2 3 4 5 
Inside the Paginator constructor method: vector split by 2 elements per page:
Page 1: 1 2 
Page 2: 3 4 
Page 3: 5 
Vector split by 2 elements per page:
Page 1: 7904336 0 
Page 2: 3 4 
Page 3: 5 

不知何故,第一页的前两个元素丢失了。但是,在类构造函数中,它似乎一切正常......我没有找到正确调试它的方法...... :(请帮忙!

感谢@Jarod42 指出了在构造函数中创建并最终在构造函数完成后删除的临时向量,我遇到了迭代器问题。所以我调整了代码。即使它可能只是有点帮助,我在下面提供了正确的代码:

线条

obj = vector(start,stop);
pages = Paginate(obj,page_size);

应该替换为

        int counter = 0;
        terator slice_start, slice_stop;
        do {
            slice_start = start+counter*page_size;
            slice_stop = next(start+counter*page_size,min(page_size,stop-start-counter*page_size));
            IteratorRange<Iterator> page = IteratorRange(slice_start,slice_stop);
            pages.push_back(page);
            ++counter;
        } while (pages.back().end() != stop);  

谢谢!

标签: c++templatesiterator

解决方案


推荐阅读