我正在使用自己的自定义迭代器实现自己的自定义静态数组容器。由于某种原因,尽管程序成功编译,std :: sort仍未对我的容器产生预期的作用
我相信我已经实现了所有必要的迭代器方法
template<typename T>
class ArrayIterator : public std::iterator<std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&> {
private:
T* m_frontPointer;
T* m_backPointer;
T* m_currentPointer;
void _checkRange(const std::ptrdiff_t movement) const {
const T* destination = m_currentPointer + movement;
if (destination < m_frontPointer || destination > m_backPointer) {
throw std::out_of_range("iterator out of range");
}
}
void _checkPosition(void) const {
if (m_currentPointer < m_frontPointer || m_currentPointer >= m_backPointer) {
throw std::logic_error("iterator out of range");
}
}
public:
ArrayIterator(T* frontPointer, T* backPointer, T* currentPointer) {
m_frontPointer = frontPointer;
m_backPointer = backPointer;
m_currentPointer = currentPointer;
}
~ArrayIterator(void) {
}
operator ArrayIterator<const T>(void) const {
return ArrayIterator<const T>(m_frontPointer, m_backPointer, m_currentPointer);
}
operator bool(void) const {
m_currentPointer != nullptr;
}
ArrayIterator<T>& operator=(const ArrayIterator<T>& iter) {
m_frontPointer = iter.m_frontPointer;
m_backPointer = iter.m_backPointer;
m_currentPointer = iter.m_currentPointer;
return *this;
}
ArrayIterator<T>& operator+=(const std::ptrdiff_t movement) {
this->_checkRange(movement);
m_currentPointer += movement;
return *this;
}
ArrayIterator<T>& operator-=(const std::ptrdiff_t movement) {
this->_checkRange(-movement);
m_currentPointer -= movement;
return *this;
}
ArrayIterator<T>& operator++(void) {
this->_checkRange(1);
++m_currentPointer;
return *this;
}
ArrayIterator<T>& operator--(void) {
this->_checkRange(-1);
--m_currentPointer;
return *this;
}
ArrayIterator<T> operator++(std::ptrdiff_t) {
this->_checkRange(1);
ArrayIterator<T> iter(m_frontPointer, m_backPointer, m_currentPointer);
++m_currentPointer;
return iter;
}
ArrayIterator<T> operator--(std::ptrdiff_t) {
this->_checkRange(-1);
ArrayIterator<T> iter(m_frontPointer, m_backPointer, m_currentPointer);
--m_currentPointer;
return iter;
}
ArrayIterator<T> operator+(const std::ptrdiff_t movement) const {
this->_checkRange(movement);
return ArrayIterator(m_frontPointer, m_backPointer, m_currentPointer + movement);
}
friend ArrayIterator<T> operator+(const std::ptrdiff_t movement, const ArrayIterator<T>& iter) {
iter._checkRange(movement);
return ArrayIterator(iter.m_frontPointer, iter.m_backPointer, iter.m_currentPointer + movement);
}
ArrayIterator<T> operator-(const std::ptrdiff_t movement) const {
this->_checkRange(-movement);
return ArrayIterator(m_frontPointer, m_backPointer, m_currentPointer - movement);
}
std::ptrdiff_t operator-(const ArrayIterator<T>& iter) const {
return std::distance(m_currentPointer, iter.m_currentPointer);
}
std::ptrdiff_t operator-(ArrayIterator<const T>& iter) const {
return std::distance(m_currentPointer, iter.m_currentPointer);
}
T& operator*(void) {
this->_checkPosition();
return *(m_currentPointer);
}
const T& operator*(void) const {
this->_checkPosition();
return *(m_currentPointer);
}
T* operator->(void) {
this->_checkPosition();
return m_currentPointer;
}
const T* operator->(void) const {
this->_checkPosition();
return m_currentPointer;
}
bool operator==(const ArrayIterator<T>& iter) const {
return m_frontPointer == iter.m_frontPointer &&
m_backPointer == iter.m_backPointer &&
m_currentPointer == iter.m_currentPointer;
}
bool operator!=(const ArrayIterator<T>& iter) const {
return !(*this == iter);
}
bool operator<(const ArrayIterator<T>& iter) const {
return m_currentPointer < iter.m_currentPointer;
}
bool operator>(const ArrayIterator<T>& iter) const {
return m_currentPointer > iter.m_currentPointer;
}
bool operator<=(const ArrayIterator<T>& iter) const {
return m_currentPointer <= iter.m_currentPointer;
}
bool operator>=(const ArrayIterator<T>& iter) const {
return m_currentPointer >= iter.m_currentPointer;
}
};
由于某种原因,当调用std :: sort时,它无法对容器进行任何更改
这是我的整个Array类:
template<typename E, std::size_t Size>
class Array {
private:
template<typename T>
class _ArrayIterator {
private:
T* m_frontPointer;
T* m_backPointer;
T* m_currentPointer;
void _checkRange(const std::ptrdiff_t movement) const {
const T* destination = m_currentPointer + movement;
if (destination < m_frontPointer || destination > m_backPointer) {
throw std::out_of_range("iterator out of range");
}
}
void _checkPosition(void) const {
if (m_currentPointer < m_frontPointer || m_currentPointer > m_backPointer) {
throw std::logic_error("iterator out of range");
}
}
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = E&;
_ArrayIterator(T* frontPointer = nullptr, T* backPointer = nullptr, T* currentPointer = nullptr) {
m_frontPointer = frontPointer;
m_backPointer = backPointer;
m_currentPointer = currentPointer;
}
_ArrayIterator(const _ArrayIterator<T>& iter) {
m_frontPointer = iter.m_frontPointer;
m_backPointer = iter.m_backPointer;
m_currentPointer = iter.m_currentPointer;
}
~_ArrayIterator(void) {
}
operator _ArrayIterator<const T>(void) const {
return _ArrayIterator<const T>(m_frontPointer, m_backPointer, m_currentPointer);
}
_ArrayIterator<T>& operator=(const _ArrayIterator<T>& iter) {
m_frontPointer = iter.m_frontPointer;
m_backPointer = iter.m_backPointer;
m_currentPointer = iter.m_currentPointer;
return *this;
}
_ArrayIterator<T>& operator+=(const std::ptrdiff_t movement) {
this->_checkRange(movement);
m_currentPointer += movement;
return *this;
}
_ArrayIterator<T>& operator-=(const std::ptrdiff_t movement) {
this->_checkRange(-movement);
m_currentPointer -= movement;
return *this;
}
_ArrayIterator<T>& operator++(void) {
this->_checkRange(1);
++m_currentPointer;
return *this;
}
_ArrayIterator<T>& operator--(void) {
this->_checkRange(-1);
--m_currentPointer;
return *this;
}
_ArrayIterator<T> operator++(std::ptrdiff_t) {
this->_checkRange(1);
_ArrayIterator<T> iter(m_frontPointer, m_backPointer, m_currentPointer);
++m_currentPointer;
return iter;
}
_ArrayIterator<T> operator--(std::ptrdiff_t) {
this->_checkRange(-1);
_ArrayIterator<T> iter(m_frontPointer, m_backPointer, m_currentPointer);
--m_currentPointer;
return iter;
}
_ArrayIterator<T> operator+(const std::ptrdiff_t movement) const {
this->_checkRange(movement);
return _ArrayIterator(m_frontPointer, m_backPointer, m_currentPointer + movement);
}
friend _ArrayIterator<T> operator+(const std::ptrdiff_t movement, const _ArrayIterator<T>& iter) {
iter._checkRange(movement);
return _ArrayIterator(iter.m_frontPointer, iter.m_backPointer, iter.m_currentPointer + movement);
}
_ArrayIterator<T> operator-(const std::ptrdiff_t movement) const {
this->_checkRange(-movement);
return _ArrayIterator(m_frontPointer, m_backPointer, m_currentPointer - movement);
}
std::ptrdiff_t operator-(const _ArrayIterator<T>& iter) const {
return std::distance(m_currentPointer, iter.m_currentPointer);
}
std::ptrdiff_t operator-(_ArrayIterator<const T>& iter) const {
return std::distance(m_currentPointer, iter.m_currentPointer);
}
T& operator*(void) {
this->_checkPosition();
return *m_currentPointer;
}
const T& operator*(void) const {
this->_checkPosition();
return *m_currentPointer;
}
T& operator[](const std::ptrdiff_t movement) {
this->_checkRange(movement);
return *m_currentPointer;
}
const T& operator[](const std::ptrdiff_t movement) const {
this->_checkRange(movement);
return *m_currentPointer;
}
T* operator->(void) {
this->_checkPosition();
return m_currentPointer;
}
const T* operator->(void) const {
this->_checkPosition();
return m_currentPointer;
}
bool operator==(const _ArrayIterator<T>& iter) const {
return m_frontPointer == iter.m_frontPointer &&
m_backPointer == iter.m_backPointer &&
m_currentPointer == iter.m_currentPointer;
}
bool operator!=(const _ArrayIterator<T>& iter) const {
return !(*this == iter);
}
bool operator<(const _ArrayIterator<T>& iter) const {
return m_currentPointer < iter.m_currentPointer;
}
bool operator>(const _ArrayIterator<T>& iter) const {
return m_currentPointer > iter.m_currentPointer;
}
bool operator<=(const _ArrayIterator<T>& iter) const {
return m_currentPointer <= iter.m_currentPointer;
}
bool operator>=(const _ArrayIterator<T>& iter) const {
return m_currentPointer >= iter.m_currentPointer;
}
};
E* m_elementData;
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using value_type = E;
using reference = E&;
using const_reference = const E&;
using pointer = E*;
using const_pointer = const E*;
using iterator = _ArrayIterator<E>;
using const_iterator = _ArrayIterator<const E>;
/*using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;*/
Array(void) {
m_elementData = new E[Size];
}
Array(const Array<E, Size>& arr) : Array() {
for (std::size_t index = 0; index < Size; ++index) {
m_elementData[index] = arr.m_elementData[index];
}
}
Array(Array<E, Size>&& arr) : Array() {
for (std::size_t index = 0; index < Size; ++index) {
m_elementData[index] = std::move(arr.m_elementData[index]);
}
}
Array(std::initializer_list<E> initList) : Array() {
typename std::initializer_list<E>::iterator iter = initList.begin();
std::size_t index = 0;
while (iter != initList.end()) {
m_elementData[index] = *iter;
++index;
++iter;
}
}
~Array(void) {
delete[] m_elementData;
}
std::size_t size(void) const noexcept {
return Size;
}
std::size_t maxSize(void) const noexcept {
return Size;
}
bool empty(void) const noexcept {
return Size == 0;
}
E& at(const std::size_t index) {
if (index >= Size) {
throw std::out_of_range("index out of bounds");
}
return m_elementData[index];
}
const E& at(const std::size_t index) const {
if (index >= Size) {
throw std::out_of_range("index out of bounds");
}
return m_elementData[index];
}
E& operator[](const std::size_t index) {
return this->at(index);
}
const E& operator[](const std::size_t index) const {
return this->at(index);
}
E& front(void) {
return this->at(0);
}
const E& front(void) const {
return this->at(0);
}
E& back(void) {
return this->at(Size - 1);
}
const E& back(void) const {
return this->at(Size - 1);
}
E* data(void) noexcept {
return m_elementData;
}
const E* data(void) const noexcept {
return m_elementData;
}
void fill(const E& value) {
algorithm::fill(this->begin(), this->end(), value);
}
void swap(Array<E, Size>& arr) {
E* copy = m_elementData;
m_elementData = arr.m_elementData;
arr.m_elementData = copy;
}
template<typename T>
std::ptrdiff_t indexOf(const T& element, const std::ptrdiff_t fromIndex = 0) const {
for (std::ptrdiff_t index = fromIndex; index < Size; ++index) {
if (element == m_elementData[index]) {
return index;
}
}
return -1;
}
template<typename T>
std::ptrdiff_t lastIndexOf(const T& element, const std::ptrdiff_t fromIndex = Size - 1) const {
for (std::ptrdiff_t index = fromIndex; index >= 0; --index) {
if (element == m_elementData[index]) {
return index;
}
}
return -1;
}
template<typename T>
bool contains(const T& element) {
return this->indexOf(element) != -1;
}
void reverse(void) {
algorithm::reverse(this->begin(), this->end());
}
void sort(void) {
algorithm::sort(this->begin(), this->end());
}
template<typename Comparer>
void sort(Comparer comp) {
algorithm::sort(this->begin(), this->end(), comp);
}
template<std::size_t N>
Array<E, (N + Size)> concat(const Array<E, N>& arr) const {
Array<E, (N + Size)> concatArr;
algorithm::concat(this->begin(), this->end(), arr.begin(), arr.end(), concatArr.begin());
return concatArr;
}
/*template<std::size_t N>
friend Array<E, (N + Size)> concat(Array<E, Size>&& left, Array<E, N>&& right) {
Array<E, (N + Size)> concatArr;
algorithm::concat(
std::make_move_iterator(left.begin()),
std::make_move_iterator(left.end()),
std::make_move_iterator(right.begin()),
std::make_move_iterator(right.end()),
concatArr
);
return concatArr;
}*/
template<std::size_t N>
Array<E, (N + Size)> merge(const Array<E, N>& arr) const {
Array<E, (N + Size)> mergeArr;
algorithm::merge(this->begin(), this->end(), arr.begin(), arr.end(), mergeArr.begin());
return mergeArr;
}
template<std::size_t N, typename Comparer>
Array<E, (N + Size)> merge(const Array<E, N>& arr, Comparer comp) const {
Array<E, (N + Size)> mergeArr;
algorithm::merge(this->begin(), this->end(), arr.begin(), arr.end(), mergeArr.begin(), comp);
return mergeArr;
}
/*template<std::size_t N>
friend Array<E, (N + Size)> merge(Array<E, Size>&& left, Array<E, N>&& right) {
Array<E, (N + Size)> mergeArr;
algorithm::merge(
std::make_move_iterator(left.begin()),
std::make_move_iterator(left.end()),
std::make_move_iterator(right.begin()),
std::make_move_iterator(right.end()),
mergeArr.begin()
);
return mergeArr;
}
template<std::size_t N, typename Comparer>
friend Array<E, (N + Size)> merge(Array<E, Size>&& left, Array<E, N>&& right, Comparer comp) {
Array<E, (N + Size)> mergeArr;
algorithm::merge(
std::make_move_iterator(left.begin()),
std::make_move_iterator(left.end()),
std::make_move_iterator(right.begin()),
std::make_move_iterator(right.end()),
mergeArr.begin(),
comp
);
return mergeArr;
}*/
void rotateRight(void) {
algorithm::rotate(this->begin(), this->end());
}
/*void rotateLeft(void) {
algorithm::rotate(this->rbegin(), this->rend());
}*/
void shuffle(void) {
this->shuffle([](std::size_t bound) { return std::rand() % bound; });
}
template<typename RandomNumberGen>
void shuffle(RandomNumberGen&& generator) {
std::srand(std::time(0));
algorithm::shuffle(this->begin(), this->end(), generator);
}
iterator begin(void) noexcept {
return iterator(m_elementData, m_elementData + Size, m_elementData);
}
const_iterator begin(void) const noexcept {
return const_iterator(m_elementData, m_elementData + Size, m_elementData);
}
iterator end(void) noexcept {
return iterator(m_elementData, m_elementData + Size, m_elementData + Size);
}
const_iterator end(void) const noexcept {
return const_iterator(m_elementData, m_elementData + Size, m_elementData + Size);
}
/*reverse_iterator rbegin(void) noexcept {
return reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData + Size - 1);
}
const_reverse_iterator rbegin(void) const noexcept {
return const_reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData + Size - 1);
}
reverse_iterator rend(void) noexcept {
return reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData - 1);
}
const_reverse_iterator rend(void) const noexcept {
return const_reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData - 1);
}*/
const_iterator cbegin(void) const noexcept {
return const_iterator(m_elementData, m_elementData + Size, m_elementData);
}
const_iterator cend(void) const noexcept {
return const_iterator(m_elementData, m_elementData + Size, m_elementData + Size);
}
/*const_reverse_iterator crbegin(void) const noexcept {
return const_reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData + Size - 1);
}
const_reverse_iterator crend(void) const noexcept {
return const_reverse_iterator(m_elementData - 1, m_elementData + Size - 1, m_elementData - 1);
}*/
template<typename T>
bool operator==(const Array<T, Size>& arr) const {
for (std::size_t index = 0; index < this->size(); index++) {
if (m_elementData[index] == arr.m_elementData[index]) {
return false;
}
}
return true;
}
template<typename T>
bool operator!=(const Array<T, Size>& arr) const {
return !(*this == arr);
}
template<typename T>
bool operator<(const Array<T, Size>& arr) const {
for (std::size_t index = 0; index < this->size(); index++) {
if (m_elementData[index] < arr.m_elementData[index]) {
return true;
}
if (m_elementData[index] > arr.m_elementData[index]) {
return false;
}
}
return false;
}
template<typename T>
bool operator>(const Array<T, Size>& arr) const {
return arr < *this;
}
template<typename T>
bool operator<=(const Array<T, Size>& arr) const {
return !(*this > arr);
}
template<typename T>
bool operator>=(const Array<T, Size>& arr) const {
return !(*this < arr);
}
};
答案 0 :(得分:0)
一旦我注释掉operator bool
(因为它使某些表达式变得模棱两可),并修复了后递增和后递减采取int
而不是ptrdiff_t
,your code compiles and works for me 。在某种程度上说,有问题可能在于未显示的代码。