IterT begin() {
return data_.begin();
}
IterT end() {
return data_.end();
}
vector<vector<IterT>> data_;
Тип data_.begin()
- это не IterT
, а std::vector<std::vector<IterT>>::iterator
.
. Эти типы не конвертируются.
Простое решение - сделать begin()
и end()
return auto
.
Ваш data_
является вектором векторов итераторов.
vector<int> v{1,2,3,4};
for (auto page : Paginator(begin(v), end(v), 2)) {
// For the first iteration i expect {1, 2}, and for the second {3, 4}
}
здесь, page
"должен" быть std::vector<std::vector<int>::iterator>
. Если вы хотите, чтобы это был std::vector<int>
, вам нужно переработать ваш дизайн.
for (int i = 1; i <= parts_; ++i) {
IterT start = next(begin, (i - 1) * pageSize_);
IterT finish = next(begin, i * pageSize_);
data_.push_back({start, finish});
}
этот код имеет проблемы с проверкой границ. Он также неэффективен для итераторов без произвольного доступа.
Он генерирует vector<IterT>
с ровно 2 элементами, один начало диапазона, один конец.
Я подозреваю, что это не так то, что ты хочешь. Вам нужен vector< std::iterator_traits<IterT>::value_type >
.
template<class IterT>
class Paginator {
public:
using value_type = typename std::iterator_traits<IterT>::value_type;
Paginator(IterT begin, IterT end, std::size_t sz):
pageSize_(sz)
{
const std::size_t dist = std::distance(begin, end);
parts_ = (dist+pageSize_-1) / pageSize_;
for (std::size_t i = 0; i < parts_; ++i) {
IterT start = std::next(begin, i * pageSize_);
IterT finish = std::next(begin, (std::min)( (i+1) * pageSize_, dist ));
data_.emplace_back(start, finish);
}
}
std::size_t size() const {
return parts_;
}
auto begin() const {
return data_.begin();
}
auto end() const {
return data_.end();
}
private:
std::size_t pageSize_ = 0;
std::size_t parts_ = 0;
std::vector<std::vector<value_type>> data_;
};
Живой пример .
Если вы хотите избежать копирования, вы можете написать класс range_t
это выставляет begin
и end
и хранит два итератора. Это позволило бы сработать тому же тестовому коду без копирования данных в структуре Paginator
.
ОП содержит некоторый очевидный код c ++ 17 , но вопрос требует c ++ 11 .
Чтобы вышеперечисленное работало в c ++ 11 , добавьте:
using value_type = typename std::iterator_traits<IterT>::value_type;
using storage = std::vector<std::vector<value_type>>;
using iterator = typename storage::iterator;
затем
iterator begin() const {
и
iterator end() const {