自定义数组迭代器的取消引用运算符



我正在练习为自定义类实现随机访问迭代器:

template<typename T>
class Array{
friend class Iterator;
private:
std::unique_ptr<T[]> data;
int front_index;
//other variables
public:
class Iterator{
friend class Array<T>;
private:
int position;
public:
Iterator(int pos) {position = pos; }
//some other iterator functions
template<typename T>
T operator*(){
return data[position];
}
};
Iterator begin() const { return Iterator(front_index); }
//other Array functions(insert, delete)
};

但当我调用这个代码时:

Array<int> a;
//insert some elements
Array<int>::Iterator iter1 = a.begin();
cout << "iterator is " << *iter1 << endl; 

它给出以下错误:

C++ no operator matches these operands, operand types are: * Array<int>::Iterator 

错误似乎来自return data[position];行。如果我只写return position,代码运行,但这不是我想要的(我希望当我取消引用时,ierator返回特定位置的元素。任何输入都很感激!

它给出以下错误:

C++ no operator matches these operands, operand types are: * Array<int>::Iterator

错误似乎来自返回数据[位置];线如果我只写代码运行的返回位置,但这不是我想要的(我希望当我取消引用时,ierator返回特定位置的元素。

不应该,因为这对解决这个错误没有任何帮助。目前还不清楚你为什么会这么想。


您的示例有三个基本问题。一种是嵌套模板,其中内部模板参数遮挡外部模板参数。这在C++中是不允许的,导致以下错误:

error: declaration of template parameter 'T' shadows template parameter

简单的解决方案是对任何嵌套模板使用另一个名称。

另一个问题是你引用的问题。阅读错误消息进一步引导我们找到解决方案:

error: no match for 'operator*' (operand type is 'Array<int>::Iterator')
35 |     cout << "iterator is " << *iter1 << endl;
|                               ^~~~~~
<source>:19:15: note: candidate: 'template<class T> T Array<T>::Iterator::operator*() [with T = T; T = int]'
19 |             T operator*(){
|               ^~~~~~~~
<source>:19:15: note:   template argument deduction/substitution failed:
<source>:35:32: note:   couldn't deduce template parameter 'T'
35 |     cout << "iterator is " << *iter1 << endl;

编译器无法知道要使用什么模板参数,因为它不能从参数中推导出来,而且您没有指定任何模板参数。从技术上讲,这可以通过明确指定参数来解决:

<< iter1.operator*<int>()

但是,我质疑为什么间接运算符首先是一个模板?为什么不总是返回外部模板的T?我建议将其作为一个常规函数:

// not a template
T   // this is the outer template parameter
operator*(){

在这些修复之后可以看到第三个问题:

error: invalid use of non-static data member 'Array<int>::data'
19 |                 return data[position];

这就是您建议的更改";解决了"-从某种意义上说,程序变得形式良好。它只是没有做任何卑鄙的事。

当然,问题是迭代器没有成员data。一个典型的解决方案是存储一个指向数组元素的非拥有指针,而不仅仅是一个本身不能用来查找数组元素的位置:

T* data;
T operator*(){
return *data;

事实上,由于指针是数组的迭代器,所以如果您懒惰,您可以简单地定义一个自定义类:

using Iterator = int*;

也就是说,自定义类可以让你在编译时发现一些错误,所以这是一个很好的设计。

最新更新