我之前从未使用过迭代器,而且我在为自己编写的自定义容器类设计自定义迭代器时遇到了麻烦。
背景:使用Google Tests API,这是我拥有的两个测试用例:
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);
}
}
这是我的头文件和迭代器的代码:
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;
};
我开始和结束的错误如下:Error: Cannot overload functions distinguished by return type alone.
我知道您不允许使用相同的功能名称和相同的参数以及不同的返回类型,因此我想知道是否有更好的方法可以做到这一点?我是否正确地使用了迭代器?模板会帮助解决这个问题吗?我需要begin()
和end()
同时返回int*
和iterator
,以便我可以通过两个测试用例。有没有更好的方法来实现这一目标?
答案 0 :(得分:2)
我需要
begin()
和end()
同时返回int*
和iterator
,以便我可以传递两个测试用例。
不,你没有。期望指针的测试用例是错误的。容器为您提供返回迭代器。在你的情况下,你的迭代器可以是一个指针,但这是一个实现细节。你绝对只想要:
iterator begin();
const_iterator begin() const; // NB: const_iterator, not const iterator
然后将您的单元测试修改为RandomArray::iterator
而不是int*
。或者,更好,auto
。
注意:您的operator++()
执行后缀增量而不是前缀增量。另外const reference
是错误的类型,它应该是int& const
,并且引用本身就是const
。您想将reference
的typedef更改为int const&
。
答案 1 :(得分:0)
如果你不能用int *b = r.begin();
更改测试用例(虽然这是一个新类,为什么不呢?)那么你需要让你的迭代器类型是指针输入,或可转换为指针类型。
在第一种情况下,摆脱iterator
类并写下using iterator = int*;
using const_iterator = int const*;
。
在第二种情况下,添加转换函数operator pointer() const { return ptr; }
。
第二种情况更好,因为这允许您将来弃用转换函数。但是,修复测试用例以使用迭代器类型会更好。
答案 2 :(得分:0)
我弄清楚我做错了什么。我所要做的就是将typedef迭代器声明为int *。
更新代码:
class MyClass
{
public:
int* begin();
const int* begin() const;
int* end();
const int* end() const;
//HERE
typedef int* iterator;
typedef const int* const_iterator;
private:
size_t capacity;
int* data;
};
然后,在函数体中我将其更改为:
int* MyClass::begin()
{
return iterator(&data[0]);
}
const int* MyClass::begin() const
{
return const_iterator(&data[0]);
}
int* MyClass::end()
{
return iterator(&data[capacity]);
}
const int* MyClass::end() const
{
return const_iterator(&data[capacity]);
}