1

我正在为自定义容器定义迭代器。迭代器实现了 InputIterator 和 OutputIterator 概念。

iterator::reference和应该使用什么类型const_iterator::referenceoperator*foriterator和应该返回什么const iterator类型const_iterator

在这种iterator情况下,是否应该有两个定义operator*?如下(T是包含的值类型):

template<typename T>
class iterator {
public:
using reference = T&;
...
T& operator*() { return ...reference to the underlying storage... }
const T& operator*() const { return ...const reference to the underlying storage... }
...
};

或者只有一个:

T& operator*() const { return ...reference to the underlying storage... }

换句话说,是否const iterator允许对底层容器进行可变访问?

对于这种const_iterator情况,我是否正确猜测以下内容是正确的?

template<typename T>
class const_iterator {
public:
using reference = const T&;
...
const T& operator*() const { return ...reference to the underlying storage... }
...
};

还是应该const_iterator::reference没有T&的定义const

除了完整的答案之外,我还希望能参考权威来源,以便将来可以查找类似信息。

4

2 回答 2

3

换句话说,常量迭代器是否允许对底层容器进行可变访问?

是的。迭代器const不是迭代器const;什么是const它本身,而不是它所指向的对象。(它类似于const指针;即T* constconst std::unique_ptr<T>。)

或者 const_iterator::reference 的定义应该是没有 const 的 T& 吗?

它应该返回const T&const_iterator是一个迭代器const;这意味着不应该允许修改它所指向的内容。(它类似于指向const; 即const T*或. 的指针std::unique_ptr<const T>。)

于 2017-06-10T05:24:25.250 回答
1

iterator::reference 和 const_iterator::reference 应该使用什么类型?

如果您想找出应该为迭代器特征( , 等)分配什么类型iterator::referenceiterator::pointer您可以尝试模仿什么std::vector,编译后的以下程序将告诉您您需要知道的一切(现场演示

#include <vector>

template <typename...>
struct WhichType;

int main() {
    auto vec = std::vector<int>{};
    WhichType<typename decltype(vec.begin())::difference_type>{};
    WhichType<typename decltype(vec.begin())::value_type>{};
    WhichType<typename decltype(vec.begin())::pointer>{};
    WhichType<typename decltype(vec.begin())::reference>{};
    WhichType<typename decltype(vec.begin())::iterator_category>{};

    WhichType<typename decltype(vec.cbegin())::difference_type>{};
    WhichType<typename decltype(vec.cbegin())::value_type>{};
    WhichType<typename decltype(vec.cbegin())::pointer>{};
    WhichType<typename decltype(vec.cbegin())::reference>{};
    WhichType<typename decltype(vec.cbegin())::iterator_category>{};
}

operator* 应该为迭代器、常量迭代器和常量迭代器返回什么类型?

operator*对于常规的非const_迭代器,应该返回对底层类型的可变引用,如果容器的语义允许,则没有歧义。例如std::map,迭代器返回对键类型的 const 引用,因为不应在 a 中修改键std::map(请参阅https://stackoverflow.com/a/32510343/5501675

const iterator传达了相同的含义T* constconst std::unique_ptr<int>确实,它们表示指向非 const 数据的 const 指针。所以你可以使用指针来修改它们指向的数据,但是你不能修改指针本身。在这种情况下,迭代器就像一个指针。所以你不能修改迭代器,但你可以修改迭代器指向的东西(现场演示

由于迭代器是const您不能调用operator++()(或预增量运算符)将迭代器推进到下一个位置。您不能这样做,因为该方法不是 const。因此,大多数代码从不使用本身为 const 的迭代器。最好使用对基础类型的 const 引用。

const_iterator定义为解决迭代器返回对基础类型的 const 引用的问题。因此它们返回对基础类型的 const 引用。 现场演示

至于它应该有什么类型定义,编译时的第一个代码示例应该告诉你

const 迭代器是否允许对底层容器进行可变访问?

是的,如果容器有。例如,允许std::vector<int>,而std::map<int, int>不允许对其键类型进行可变访问

或者 const_iterator::reference 的定义应该是没有 const 的 T& 吗?

看上面的现场演示,当你编译代码你会看到它是一个const T&

于 2017-06-10T07:08:27.887 回答