Reputation: 869
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.
Upvotes: 1
Views: 511
Reputation: 275220
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.
Upvotes: 1
Reputation: 264331
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
Upvotes: 2