Readon Shaw
Readon Shaw

Reputation: 439

Best practice on implementing object stream container in modern c++

I want to wrap some c library in modern C++ way.

The library provide a way to reverse serialize objects from binary string. So that its API appears can only forward from begin of the string to the end, where the part have been processed will not be kept, just like stream.

However it works different from standard stream, it will not support "<<" operator to return char, and for loops should not return char also. It needs a iterator which can iterator on it and return objects it generated.

at first, I want to implement code just like below:

class Obj{
  c_ptr ptr;
  .....
}

class X{
   public:
   class const_iterator : std::iterator<std::forward_iterator_tag, Obj>{
       ......
   };

   class iterator : const_iterator{
       .....
   };

   X::const_iterator cbegin();
   X::iterator begin();
   X::const_iterator cend();
   X::iterator end();
   ........
}

or merge Obj class into iterator. There are problems in this case.

1.as vector iterator example shows, begin and end() should return index value. But here X is stream, I can only get the begin once, after that access stream would not the the first byte. In iostream the end() seems return a specific char EOF.

  1. I suppose that I can not inherit X from istream? because istream seem is designed for char streams operation with lots of mechanism as overflow, etc, which are not needed for the wrapper.

  2. iterator inherit from const_iterator is suggest by some one to reduce the similar code. But it seems still have a lots of code should be different, mainly focus on it's declaration.

Is there any best practice on this kind of container or iterator implementation in modern C++?

Upvotes: 1

Views: 1450

Answers (1)

Ely
Ely

Reputation: 11174

  1. The iterators actually don't return index values. They are pointers to typed objects I think.
    In the case of vector the iterator fulfills the requirements (properties/traits/...) of a RandomAccessIterator and that's why you can access by subscript operator.
    I suggest you read upon the iterator concepts first, you might need some of the concepts four your design: InputIterator/OutputIterator, ForwardIterator (I believe this iterator is what you might consider probably), etc.
    begin() usually always points to the beginning of the container and end() usually always points to the end of the container. In STL I don't know about an exception of that. Also it can be that some operations of the container can invalidate an iterator (which I believe is likely in your use case). In your case, you first need to be clear of your use case/requirement for your stream design.

  2. You're probably right. And it is not a good idea to extend a class and change the semantics of derived methods, etc.

  3. It depends what you want to do with your stream. Simply iterate over elements in read-only mode? Or do you need to be able to write? Or in reverse? There are four kinds: iterator, const_iterator, reverse_iterator and const_reverse_iterator.

The best practice is the STL, though very difficult to digest. I recommend the book The C++ Programming Language where you can learn about the ideas, design, use cases, etc.

Upvotes: 1

Related Questions