#include <iostream>
#include <vector>
#include <algorithm>
template <typename T>
class _iterator
{
T* ptr;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using reference = T&;
using pointer = T*;
using difference_type = unsigned long long;
_iterator(T* ptr) : ptr(ptr) {}
reference operator* () { return *ptr; }
pointer operator->() { return ptr; }
_iterator& operator++() { ptr++; return *this; }
_iterator& operator--() { ptr--; return *this; }
difference_type operator-(const _iterator& it) { return this->ptr - it.ptr; }
_iterator operator+(const difference_type& diff) { return _iterator(ptr + diff); }
_iterator operator-(const difference_type& diff) { return _iterator(ptr - diff); }
bool operator==(const _iterator& it) { return this->ptr == it.ptr; }
bool operator!=(const _iterator& it) { return this->ptr != it.ptr; }
bool operator< (const _iterator& it) { return this->ptr < it.ptr; }
operator _iterator<const T>() const { return _iterator<const T>(ptr); }
};
template <typename T>
class X
{
std::vector<T> data;
public:
using iterator = _iterator<T>;
using const_iterator = _iterator<const T>;
void push_back(T t)
{
data.push_back(t);
}
iterator begin()
{
return iterator(&data[0]);
}
iterator end()
{
return iterator(&data[0] + data.size());
}
};
int main()
{
X<int> x;
for (int i = 9; i >= 0; i--)
x.push_back(i);
// 1 ------------------------------------------------------------------------
// C2780 'void std::_Sort_unchecked(_RanIt,_RanIt,iterator_traits<_Iter>::difference_type,_Pr)': expects 4 arguments - 3 provided
// C2672 '_Sort_unchecked': no matching overloaded function found
// C2678 binary '-': no operator found which takes a left - hand operand of type 'const _RanIt' (or there is no acceptable conversion)
std::sort(x.begin(), x.end());
// 2 ------------------------------------------------------------------------
// C2666 '_iterator<T>::operator -': 2 overloads have similar conversions
// C2512 '_iterator<T>': no appropriate default constructor available
for (X<int>::iterator it = x.end() - 1; it >= x.begin(); --it)
std::cout << *it << ' ';
std::cout << std::endl;
}
I'm trying to write a random access iterator for a custom container. I'm facing couple of problems:
Errors are written above each peice of code corresponding to it. Also I'm not sure if the way I'm defining iterator
and const_iterator
is a valid way or not. What am I doing wrong here and how to fix them?
// C2678 binary '-': no operator found which takes a left - hand operand of type 'const _RanIt' (or there is no acceptable conversion)
If you mark the following function as const
:
difference_type operator-(const _iterator& it) const { return this->ptr - it.ptr; }
You'll start fixing some of the problems. I didn't check if this covered all the cases. But in general, making everything you can const
helps a lot.
I needed to mark the functions and operators as const
as well as writing a difinition for the operator[]
. Optionally I can providing the reset of the relational operators ( >
, >=
, <=
) in case I wanted to use them. Here is the working code:
#include <iostream>
#include <vector>
#include <algorithm>
template <typename T>
class _iterator
{
T* ptr;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using reference = T&;
using pointer = T*;
using difference_type = unsigned long long;
_iterator(T* ptr) : ptr(ptr) {}
reference operator* () const { return *ptr; }
pointer operator->() const { return ptr; }
_iterator& operator++() { ptr++; return *this; }
_iterator& operator--() { ptr--; return *this; }
difference_type operator-(const _iterator& it) const { return this->ptr - it.ptr; }
_iterator operator+(const difference_type& diff) const { return _iterator(ptr + diff); }
_iterator operator-(const difference_type& diff) const { return _iterator(ptr - diff); }
reference operator[] (const difference_type& offset) const { return *(*this + offset); }
bool operator==(const _iterator& it) const { return this->ptr == it.ptr; }
bool operator!=(const _iterator& it) const { return this->ptr != it.ptr; }
bool operator< (const _iterator& it) const { return this->ptr < it.ptr; }
bool operator> (const _iterator& it) const { return this->ptr > it.ptr; }
bool operator>=(const _iterator& it) const { return !(this->ptr < it.ptr); }
bool operator<=(const _iterator& it) const { return !(this->ptr > it.ptr); }
operator _iterator<const T>() const { return _iterator<const T>(ptr); }
};
template <typename T>
class X
{
std::vector<T> data;
public:
using iterator = _iterator<T>;
using const_iterator = _iterator<const T>;
void push_back(T t)
{
data.push_back(t);
}
iterator begin()
{
return iterator(&data[0]);
}
iterator end()
{
return iterator(&data[0] + data.size());
}
};
int main()
{
X<int> x;
for (int i = 0; i < 10; i++)
x.push_back(i);
std::sort(x.begin(), x.end(), std::greater<>());
for (X<int>::iterator it = x.end() - 1; it >= x.begin(); --it)
std::cout << *it << ' ';
std::cout << std::endl;
}
Output:
0 1 2 3 4 5 6 7 8 9
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.