2013-03-07 118 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