迭代器和 Const 迭代器在C++?
Iterators and Const iterators in C++?
假设我有两个类,第一个:
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}; }
演示
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?