讓我們來考慮一個非常基本的範圍適配器類,它圍繞一個範圍進行打包,並在遍歷適配器時迭代原始範圍的每個其他元素。在範圍適配器的迭代器類中實現運算符 - >
for (const auto & e : everyOtherElement(originalRange))
當寫這樣的範圍適配器類,需要編寫一個相應的迭代器類爲該適配器,使其可迭代和行爲像期望的。
這樣的迭代器類應該實現您希望它支持的「概念」所需的所有內容,例如InputIterator
。除其他外,我們應該執行operator*
以返回對代表元素的引用,以及operator->
,以便it->member
訪問該元素的成員。
我認爲這將是一個好主意,只是「前進」這些運營商底層迭代器適配器環繞的實現(讓我們忘掉常量性了一會兒):
struct everyOtherElement {
OriginalIterator b, e; // The begin and end we wrap around
// ...
struct iterator {
OriginalIterator it;
auto operator*() { return *it; } // <------
auto operator->() { return it.operator->(); } // <------
// ...
};
};
但是,如果OriginalIterator
是指針類型,則operator->
無法編譯,就像大多數std::vector
實現以及原始數組一樣。由於這種迭代器是非類型的,因此不允許編寫it.operator->()
。
我該如何實現operator->
才能使迭代器儘可能透明?我是否應該按照operator*
執行operator->
,即像編寫(*it).m
而不是it->m
。我猜這會失敗,如果一些迭代器實現它們意味着不同的事情...(雖然這將是邪惡的,不是嗎?或者被InputIterator
概念禁止?)
它是一個好主意來實現它作爲剛剛返回的原始迭代器,因爲operator->
是遞歸自動應用,只要返回一個非指針?
auto operator->() { return it; }
正如我假設有涉及模板,我會建議僅使用SFINAE /標籤調度來選擇實現,具體取決於OriginalIterator是否爲指針。 –