2013-03-07 116 views
1

我在製作一個使用數據結構的庫:std::vector<std::string>。我需要滿足API,它說,爲了通過我的數據迭代結構的用戶就必須做到以下幾點:自定義迭代器

for (lib::result::const_iterator it = data.begin(); it != data.end(); it++) 

有兩種方法我能做到這一點,我自己實現lib::result::const_iterator或繼承std::vector<std::string>::iterator,他們都應該工作。我已經讀過,從矢量迭代器繼承是一個壞主意。

我決定使用Boost迭代器外觀,這是一個好主意嗎? 另外,我在執行increment()時遇到問題。如果我有一個指向std :: vector中的字符串的指針,我該如何指向下一個字符串?

最後,我的實現可以從std::vector<std::string>改變,以std::vector<MyDatatype>,所以我想用升壓門面所以要是我決定更改我的數據結構,事情會更容易些。 謝謝。

+5

你不需要繼承,只是'typedef'它 – 2013-03-07 14:52:19

回答

1
namespace lib { 
    struct class { 
    typedef std::vector<std::string>::const_iterator const_iterator; 
    const_iterator begin() const; 
    const_iterator end() const; 
    }; 
}; 

如果你改變的基本類型,假設迭代器與std::vector<std::string>迭代器兼容,只是改變的typedef。如果它與迭代器std::vector<std::string>不兼容,那麼你正在破壞你的API。然而,這真的是另一天的問題。

如果你確實需要實現一個迭代器,boost的「迭代器適配器」是一個不錯的選擇:用你的迭代器包裝0​​迭代器。

如果我必須通過庫版本更改生成一個穩定的二進制接口,那麼我可能會使用「迭代器fascade」。在這種情況下,我的「迭代器外觀」將轉發到一個接口(它重複了「迭代器外觀」從其實現中要求的方法),該接口實現了外觀的每個功能。然後內部pImpl實現將以類似於「迭代器適配器」的方式將方法轉發到std::vector<std::string>。但幾乎在所有情況下,這都是矯枉過正。

但是,第一種情況 - 您在typedef std::vector<std::string>::const_iterator中 - 是最有效和最容易實現的。

+1

「門面」。 (是的,'c'發音爲's'。) – aschepler 2013-03-07 15:28:22

2

您可以只使用向量迭代器:

class MyClass 
{ 
    typedef std::vector<std::string> MyData; 

    MyData data; 

    public: 
     typedef MyData::iterator  iterator; 
     typedef MyData::const_iterator const_iterator; 

     iterator  begin()  {return data.begin();} 
     const_iterator begin() const {return data.begin();} 

     .... etc