1

I am making a library using the data structure: std::vector<std::string>. I have to satisfy the API, which says that in order to iterate through my data structure users would have to do the following:

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

There are two ways I could do this, implement lib::result::const_iterator on my own or inherit from std::vector<std::string>::iterator, they should both work. I have read that inheriting from the vector iterator is a bad idea.

I have decided to use Boost iterator facade, is this a good idea? Also, I am having trouble implementing increment(). If I have a pointer to a string in an std::vector, how do I point to the next string?

Lastly, my implementation could change from std::vector<std::string>, to std::vector<MyDatatype>, so I would like to use the boost facade so if ever I decide to make changes to my data structure, things would be easier. Thanks.

1
  • 5
    you don't need to inherit, just typedef it Commented Mar 7, 2013 at 14:52

2 Answers 2

2

You can just use the vectors iterator:

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
Sign up to request clarification or add additional context in comments.

Comments

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

If you change the underlying type, assuming that the iterator is compatible with the std::vector<std::string> iterator, just change the typedef. If it isn't compatible with the std::vector<std::string> iterator, you are breaking your API. However, this really is a problem for another day.

If you do need to implement an iterator, boost's "iterator adaptor" is a good choice: wrap the std::vector<std::string> iterator with yours.

"iterator fascade" would be something I might use if I had to generate a stable binary interface over library version changes. In that case, my "iterator facade" would forward to a pImpl-type virtual interface (which repeats the methods that "iterator facade" requires from its implementation) that implemented each feature of the facade. The internal pImpl implementation would then forward the methods to the std::vector<std::string> in a way similar to how "iterator adaptor" works. But in almost all cases, this is overkill.

But the first case -- where you typedef std::vector<std::string>::const_iterator -- is both the most efficient and easiest to implement.

1 Comment

"facade". (Yes, the 'c' is pronounced 's'.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.