【发布时间】:2020-08-30 02:40:14
【问题描述】:
更新:
感谢所有提交答案的人。
简而言之,答案是begin() 和end() 返回的“迭代器”必须是可复制的。
Artyer 提出了一个很好的解决方法:创建一个包含对不可复制对象的引用(或指针)的迭代器类。下面是示例代码:
struct Element {};
struct Container {
Element element;
struct Iterator {
Container * c;
Iterator ( Container * c ) : c(c) {}
bool operator != ( const Iterator & end ) const { return c != end.c; }
void operator ++ () { c = nullptr; }
const Element & operator * () const { return c->element; }
};
Iterator begin () { return Iterator ( this ); }
Iterator end () { return Iterator ( nullptr ); }
};
#include <stdio.h>
int main () {
Container c;
printf ( "main %p\n", & c .element );
for ( const Element & e : c ) { printf ( "loop %p\n", & e ); }
return 0;
}
原问题:
下面的 C++ 代码将无法编译(至少在 Ubuntu 20.04 上使用 g++ 9.3.0 版时不会编译)。
错误信息是:use of deleted function 'Iterator::Iterator(const Iterator&)'
基于错误,我是否正确地得出结论begin() 和end() 返回的“迭代器”必须是可复制的?或者有什么方法可以使用通过引用返回的不可复制的迭代器?
struct Iterator {
Iterator () {}
// I want to prevent the copying of Iterators, so...
Iterator ( const Iterator & other ) = delete;
bool operator != ( const Iterator & other ) { return false; }
Iterator & operator ++ () { return * this; }
Iterator & operator * () { return * this; }
};
struct Container {
Iterator iterator;
Iterator & begin() { return iterator; }
Iterator & end() { return iterator; }
};
int main () {
Container container;
for ( const Iterator & iterator : container ) {}
// The above for loop causes the following compile time error:
// error: use of deleted function 'Iterator::Iterator(const Iterator&)'
return 0;
}
【问题讨论】:
-
基于范围的 for 假设它所操作的容器提供了可复制构造和可复制分配的迭代器。您的使用
for ( const Iterator & iterator : container ) {}也是错误的 - 它会依赖于begin()和end()都产生迭代器,当取消引用时,可以给出const Iterator &。 -
不可复制类型不是迭代器,因为迭代器的概念要求类型满足 CopyConstructible 的概念。
标签: c++ iterator copy-constructor range-based-loop