WitchKing17 WitchKing17 - 2 months ago 31
C++ Question

C++ Iterators return type

I've never worked with iterators before, and I'm having trouble designing a custom iterator for a custom container class that I wrote.

Background: Using Google Tests API, these are the two test cases that I have:

TEST(RandomArray, End) {
RandomArray r(17);
int *b = r.begin();
int *e = r.end();
EXPECT_EQ(b + 17, e);
}

TEST(RandomArray, IteratorTypedef) {
RandomArray r(7);
for (RandomArray::iterator it = r.begin(); it != r.end(); ++it) {
*it = 89;
EXPECT_EQ(89, *it);
}
}


Here's my header file and the code for the iterators:

class RandomArray
{
friend ostream& operator<<(ostream&, const RandomArray&);

public:
class iterator
{
public:
typedef iterator self_type;
typedef int* pointer;
typedef int& reference;
self_type operator++() { self_type i = *this; ptr++; return i;}
reference operator*() {return *ptr;}
bool operator!=(const self_type& rhs) {return ptr != rhs.ptr;}
private:
pointer ptr;
};

class const_iterator
{
public:
typedef const_iterator self_type;
typedef int* pointer;
typedef int& reference;
self_type operator++() { self_type i = *this; ptr++; return i;}
const reference operator*() { return *ptr; }
bool operator!=(const self_type& rhs) {return ptr != rhs.ptr;}
private:
pointer ptr;
};

RandomArray();

RandomArray(size_t);

size_t size() const;

int* begin();
iterator begin();

const int* begin() const;
const iterator begin() const;

int* end();
iterator end();

const int* end() const;
const iterator end() const;
private:
size_t capacity;
int* data;
};


The error I'm getting on begin and end is the following:
Error: Cannot overload functions distinguished by return type alone.


I know you're not allowed to have the same function name and same parameters with different return types, so I'm wondering if there's a better way to do this? Am I making the iterator right? Would a template help fix this? I need
begin()
and
end()
to return both an
int*
and an
iterator
so I can pass both test cases. Is there a better way to accomplish this?

Answer

I need begin() and end() to return both an int* and an iterator so I can pass both test cases.

No, you don't. The test case expecting a pointer is wrong. Containers give you back iterators. In your case, your iterator could be a pointer, but that's an implementation detail. You definitely just want:

iterator begin();
const_iterator begin() const; // NB: const_iterator, not const iterator

And then fix your unit test to expect RandomArray::iterator instead of int*. Or, even better, auto.


Note: Your operator++() does postfix increment instead of prefix increment. Also const reference is the wrong type, that woudl be int& const, and references are inherently const. You want to change your typedef for reference to itself be int const&.

Comments