2014-04-01 61 views
2

我有一個管理數據的類。爲非STL容器創建我自己的迭代器

我希望只返回其中的一部分數據,但由於它是一個多次完成的過程,我不希望只複製容器內的數據並返回容器。

這將是很好,如果我只能發送參考或類似的東西。迭代想到。但因爲我使用Eigen3矩陣(不具有迭代器(二維矩陣反正))

我想到的模擬迭代器行爲, 類似的東西(?):

typedef unsigned int Index; 

class MatrixIterator 
{ 
public: 
    MatrixIterator(Eigen::MatrixXd *m, Index min, Index max): 
     _col(0), _index(0), _min(min), _max(max), _matrix(m) 
    {} 

    void operator++() 
    { 
     if (_index + _min + 1 != _max) 
      _index++; 
    } 
    void operator--() 
    { 
     if (_index != _min) 
      _index--; 
    } 

    double operator*() 
    { 
     return _matrix->operator() (_index + _min, _col); 
    } 

    void setCol(Index col) { _col = col; } 

    Index min() { return _min; } 
    Index max() { return _max; } 

private: 
    // the matrix is 2D we can select 
    // on which column we want to iterate 
    Index _col; 

    // current position 
    Index _index; 

    // select the range on which the user can iterate 
    Index _max; 
    Index _min; 

    // the matrix on which we want to iterate over 
    Eigen::MatrixXd* _matrix; 
} 
  • 我從來沒有真正使用過迭代器,它是正確的嗎?
  • 我可以從std::iterator繼承我的MatrixIterator,因此stl能夠將其理解爲通常的迭代器嗎?
  • 你知道更好的方法來做類似的事嗎?

我已閱讀:

編輯:我想只迭代矩陣的一部分(這就是爲什麼我有_min和_max),我操縱的數據ulating是時間序列,所以數據已經訂購了。 我認爲我們可以將MatrixIterator視爲對數據查詢的響應。

回答

2

我從來沒有真正使用過迭代器,它是正確的嗎?

這是一個好的開始。這個想法是正確的,但是你錯過了一些東西。首先,你沒有足夠的運營商。確保您檢查了reference,併爲您提供的每個運營商提供合理的服務(唯一可能或不可用的運營商是隨機接入運營商,因爲在這種情況下可能難以實施)。其次,您需要爲您的迭代器類提供iterator traits。這通常是通過在你的迭代器類中創建必要的嵌套類型定義來完成的(你也可以專門爲你的類設計std::iterator_traits模板,但是我會說只有當你真的不能添加嵌套的typedefs時)。

我可以從std::iterator繼承我的MatrixIterator,這樣stl就可以把它理解爲一個通常的迭代器了嗎?

不,你一般不應該繼承std::iterator類。 STL是一個模板庫(泛型編程(GP)),因此不像在OOP中那樣使用基類繼承模型。STL算法將迭代器作爲模板參數,並按照算法的要求(或儘可能通過與迭代器類型相關的iterator_category特徵)一般使用它們。這是generic programming,不是面向對象的編程,它是蘋果和桔子。

你知道更好的方法來做類似的事嗎?

嗯,一個方便的方式做,這是通過使用類模板一樣boost::iterator_facade(見ref),它提供一種自動化「填補空白」的機制創建迭代器。它使用衆所周知的非常有用的Curiously Recurring Template Pattern(或簡稱CRTP)。這很有用,因爲實現迭代器所需的所有操作符可能非常冗長和重複,而且通常只依賴於幾個核心操作(當使用類似boost::iterator_facade的CRTP類時,您只需「填寫」)。

+0

我將嘗試boost :: iterator_facade。 謝謝~~ – Setepenre

+0

+1 boost :: iterator_facade。我之前使用過那個,它工作得非常好。有點繁瑣寫,但偉大的閱讀和使用。 –

+0

我只是想補充一點,如果你不想把自己綁定到boost庫,你可以很容易地重現一個類似'iterator_facace'的類,只需查找源代碼以獲得靈感並重現它。 –