迭代器和 Const 迭代器在C++?

Iterators and Const iterators in C++?

本文关键字:迭代器 C++ Const      更新时间:2023-10-16

假设我有两个类,第一个:

class IntMatrix::iterator {
private:
const IntMatrix *int_matrix;
int index;
iterator(const IntMatrix *int_matrix, int index);
friend class IntMatrix;
public:
int &operator*() const;
iterator &operator++();
iterator operator++(int);
bool operator==(const iterator &it) const;
bool operator!=(const iterator &it) const;
iterator(const iterator &) = default;
iterator &operator=(const iterator &) = default;
~iterator() = default;
};

第二个是:

class IntMatrix::const_iterator {
private:
const IntMatrix *int_matrix;
int index;
const_iterator(const IntMatrix *int_matrix, int index);
friend class IntMatrix;
public:
const int &operator*() const;
const_iterator &operator++();
const_iterator operator++(int);
bool operator==(const const_iterator &it) const;
bool operator!=(const const_iterator &it) const;
const_iterator(const const_iterator &) = default;
const_iterator &operator=(const const_iterator &) = default;
~const_iterator() = default;
};

由于实现 99% 相同,我如何防止此处的代码重复?泛型在这里或继承方面是否有帮助?

它们如何实现的示例:

int &IntMatrix::iterator::operator*() const {
return int_matrix->data[index];
}
const int &IntMatrix::const_iterator::operator*() const {
return int_matrix->data[index];
}

另外,我希望 In main 允许类似的东西:

IntMatrix::iterator it;

更新: 我正在尝试通过以下方式在名为 Matrix 的泛型类上实现给定的解决方案:(请注意,显示的代码在我的类中都是作为公共编写的(

template<typename T>
class iterator_impl;
template<typename T>
iterator_impl<T> begin(){
return iterator(this, 0);
}
template<typename T>
iterator_impl<T> end(){
return iterator(this, size());
}
template<typename T>
iterator_impl<const T> begin() const
{
return const_iterator(this, 0);
}
template<typename T>
iterator_impl<const T> end() const
{
return const_iterator(this, size());
}
template<typename T>
class iterator_impl{
private:
const Matrix<T> *matrix;
int index;
friend class Matrix<T>;
public:
iterator_impl(const iterator_impl &) = default;
iterator_impl &operator=(const iterator_impl &) = default;
~iterator_impl() = default;
iterator_impl(const Matrix<T> *int_matrix, int index)
: matrix(int_matrix), index(index) {}
iterator_impl &operator++()
{
++index;
return *this;
}
iterator_impl operator++(int)
{
iterator_impl result = *this;
++*this;
return result;
}
bool operator==(const iterator_impl &it) const
{
return index == it.index;
}
bool operator!=(const iterator_impl &it) const
{
return !(*this == it);
}
T &operator*() const {
if (index < 0 || index > matrix->size() - 1) {
throw Matrix<T>::AccessIllegalElement();
}
return matrix->data[index];
}
};
template<typename T>
using iterator = iterator_impl<T>;
template<typename T>
using const_iterator = iterator_impl<const T>;

我收到一些错误,例如:

在非静态成员函数外部无效使用"this" 返回迭代器(this, 0(;

一种方法是将实现制作成类模板,然后为const和非const实例创建别名。

另外,我希望 In main 允许类似的东西:IntMatrix::iterator it;

然后,需要添加默认构造函数。

例:

#include <cstddef>
#include <type_traits>
// in the .hpp file:
class IntMatrix {
private:
int data[10];     // just an example
size_t size = 10; // just an example
template<typename T>
class iterator_impl;
public:
// two typedefs using the template:
using iterator = iterator_impl<int>;
using const_iterator = iterator_impl<const int>;
const_iterator cbegin() const;
const_iterator cend() const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
};
// still in the .hpp file:
template<typename T>
class IntMatrix::iterator_impl {
public:
using matrix_type =
std::conditional_t<
std::is_const_v<T>,
const IntMatrix,
IntMatrix
>;
private:
matrix_type* int_matrix;
size_t index;
friend IntMatrix;
iterator_impl(matrix_type* im, size_t idx) :
int_matrix(im), index(idx)
{}
public:
iterator_impl() = default;                          // default constructor
//iterator_impl(const iterator_impl&) = default;             // not needed
//iterator_impl &operator=(const iterator_impl &) = default; // not needed
//~iterator_impl() = default;                                // not needed
iterator_impl &operator++() {
++index;
return *this;
}
iterator_impl operator++(int) {
iterator_impl old(*this);
++index;
return old;
}
bool operator!=(const iterator_impl &it) const {
return index != it.index || int_matrix != it.int_matrix;
}
bool operator==(const iterator_impl &it) const {
return !(*this != it);
}
T& operator*() const {
return int_matrix->data[index];
}
};
// in the .cpp file:
IntMatrix::const_iterator IntMatrix::cbegin() const { return {this, 0}; }
IntMatrix::const_iterator IntMatrix::cend() const { return {this, size}; }
IntMatrix::const_iterator IntMatrix::begin() const { return cbegin(); }
IntMatrix::const_iterator IntMatrix::end() const { return cend(); }
IntMatrix::iterator IntMatrix::begin() { return {this, 0}; }
IntMatrix::iterator IntMatrix::end() { return {this, size}; }

演示


编辑:如果Matrix是类模板本身,则需要稍微更改迭代器。

#include <cstddef>
#include <type_traits>
// in the .hpp file:
template<typename T>
class Matrix {
private:
T data[10];       // just an example
size_t size = 10; // just an example
template<typename I>
class iterator_impl;
public:
// two typedefs using the template:
using iterator = iterator_impl<T>;
using const_iterator = iterator_impl<const T>;
auto cbegin() const;
auto cend() const;
auto begin() const;
auto end() const;
auto begin();
auto end();
};
// still in the .hpp file:
template<typename T>
template<typename I>
class Matrix<T>::iterator_impl {
public:
using value_type = std::remove_const_t<I>;
using matrix_type =
std::conditional_t<
std::is_const_v<I>,
const Matrix<value_type>,
Matrix<value_type>
>;
private:
matrix_type* matrix;
size_t index;
friend Matrix;
iterator_impl(matrix_type* im, size_t idx) :
matrix(im), index(idx)
{}
public:
iterator_impl() = default;                          // default constructor
iterator_impl& operator++() {
++index;
return *this;
}
iterator_impl operator++(int) {
iterator_impl old(*this);
++index;
return old;
}
bool operator!=(const iterator_impl &it) const {
return index != it.index || matrix != it.matrix;
}
bool operator==(const iterator_impl &it) const {
return !(*this != it);
}
I& operator*() const {
return matrix->data[index];
}
};
// still in the .hpp file
template<typename T> auto Matrix<T>::cbegin() const { return const_iterator{this, 0}; }
template<typename T> auto Matrix<T>::cend() const { return const_iterator{this, size}; }
template<typename T> auto Matrix<T>::begin() const { return cbegin(); }
template<typename T> auto Matrix<T>::end() const { return cend(); }
template<typename T> auto Matrix<T>::begin() { return iterator{this, 0}; }
template<typename T> auto Matrix<T>::end() { return iterator{this, size}; }

演示