2016-01-22 44 views
1

讓我們來考慮一個非常基本的範圍適配器類,它圍繞一個範圍進行打包,並在遍歷適配器時迭代原始範圍的每個其他元素。在範圍適配器的迭代器類中實現運算符 - >

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; } 
+0

正如我假設有涉及模板,我會建議僅使用SFINAE /標籤調度來選擇實現,具體取決於OriginalIterator是否爲指針。 –

回答