簡體   English   中英

InputIterator和OutputIterator的`operator *`返回值的常數的規則是什么?

[英]What are the rules governing constness of `operator*` return value for InputIterator and OutputIterator?

我正在為自定義容器定義迭代器。 迭代器同時實現InputIterator和OutputIterator概念。

iterator::referenceconst_iterator::reference應該使用什么類型? operator*應該為iteratorconst iteratorconst_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

除了完整的答案之外,我還希望引用權威資料,以后我可以在其中查找相似的信息。

換句話說,const迭代器是否允許對底層容器的可變訪問?

是。 const迭代器不是一個迭代const ; const本身就是它本身,而不是它指向的對象。 (類似於const指針;即T* constconst std::unique_ptr<T> 。)

還是const_iterator :: reference的定義應該是T&而沒有const?

它應該返回const T& const_iteratorconst的迭代器; 這意味着它所指向的內容不得被修改。 (類似於指向const的指針;即const T*std::unique_ptr<const T> 。)

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>{};
}

運算符*應該為迭代器,常量迭代器和const_iterator返回什么類型?

常規非const_迭代器的operator*應該返回對基礎類型的可變引用,如果容器的語義允許,則那里沒有歧義。 例如, std::map迭代器返回對鍵類型的const引用,因為不應在std::map修改鍵(請參閱https://stackoverflow.com/a/32510343/5501675

const iterator傳達的含義與T* constconst std::unique_ptr<int>含義相同,它們表示指向非const數據的const指針。 因此,您可以使用指針來修改它們指向的數據,但是不能修改指針本身。 在這種情況下,迭代器的作用類似於指針。 因此,您不能修改迭代器,但是可以修改迭代器指向的內容( 實時演示

由於迭代器是const ,因此無法調用operator++() (或preincrement運算符)將迭代器前進到下一個位置。 您不能執行此操作,因為該方法不是const。 因此,大多數代碼從不使用本身就是常量的迭代器。 您最好使用對基礎類型的const引用。

定義const_iterator是為了解決迭代器將const引用返回給基礎類型的問題。 因此,它們返回對基礎類型的const引用。 現場演示

至於它應該有什么類型定義,編譯時的第一個代碼示例應該告訴您

const迭代器是否允許對底層容器的可變訪問?

是的,如果容器這樣做了。 例如std::vector<int>可以,而std::map<int, int>不允許對其鍵類型的可變訪問

還是const_iterator :: reference的定義應該是T&而沒有const?

參見上面的實時演示,在編譯代碼時,您將看到它是一個const T&

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM