c++ - 无法转换类型C++

标签 c++ c++11

我正在实现自定义分页器。
例如。

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}
}
我的代码有错误:

/home/alex/dev/main.cpp:32:28: error: could not convert ‘((Paginator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >*)this)->Paginator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >::data_.std::vector<_Tp, _Alloc>::begin<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > >, std::allocator<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > > > >()’ from ‘std::vector<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > >, std::allocator<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > > > >::iterator {aka __gnu_cxx::__normal_iterator<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > >*, std::vector<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > >, std::allocator<std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > > > > >}’ to ‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’

return data_.begin();


我的代码
template<class IterT>
class Paginator {
public:
    Paginator(IterT begin, IterT end, size_t sz) {
        pageSize_ = sz;
        const size_t dist = distance(begin, end);
        parts_ = dist / pageSize_;
        if (dist % pageSize_ != 0) {
            ++parts_;
        }
        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});
        }
    }

    size_t size() const {
        return parts_;
    }

    IterT begin() {
        return data_.begin();
    }

    IterT end() {
        return data_.end();
    }


private:
    size_t pageSize_;
    size_t parts_;
    vector<vector<IterT>> data_;
};

template<class T>
void Print(const vector<T>& v) {
    for (auto i : v) {
        cout << i << ' ';
    }
    cout << endl;
}

int main() {
    vector<int> v{1,2,3,4,5,6,7,8,9};


    for (auto i : Paginator<vector<int>::iterator>(begin(v), end(v), 2)) {
        Print(i);
    }
}

最佳答案

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()返回auto

您的data_是迭代器 vector 的 vector 。
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});
    }

该代码具有边界检查问题。对于非随机访问迭代器,它的效率也不高。

它生成一个正好包含2个元素的vector<IterT>,一个是范围的开始,一个是结束。

我怀疑这不是您想要的。您想要的是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_;
};

Live example

如果要避免复制内容,可以编写一个range_t类,该类公开beginend并存储两个迭代器。这将使相同的测试代码有效,而无需在Paginator结构中复制数据。

OP包含一些明显的代码,但问题要求输入

要使以上工作在中,请添加:
  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 {

关于c++ - 无法转换类型C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60084094/

相关文章:

c++ - 删除构造函数后的初始化

c++ - C++11 的 long long 真的至少 64 位吗?

c++ - 如何向后输出char数组中的每个单词

c++ - 我应该什么时候使用 [[maybe_unused]]?

c++ - 有没有办法确定 C++ 编译器实现的语言特性?

c++ - 一个 vector/映射中的 std::function 变量参数

gcc 的 C++ 部分模板特化问题

c++ - 迭代求和中的段错误

c++ - 为什么我的程序不执行第二个 catch block ?

c++ - 重载采用 chrono::duration 的函数