Question

Actually, I have a design question here. Its very simple but the point is:

I have one C++ class that has a STL vector declared as a private member. But the clients of that class need to iterate over this vector.

In C# we have a very handy statement, the Yield, that in cases like that, you write a function returning an IEnumerable and it "yields" you a nice way to iterate over a private container inside that class.

I'm just trying to find an elegant solution for C++, instead of using methods like GetValue(int idx).

Any suggestions?

Example:

class Fat
{
   public:
      Fat();
   // some code here ...

   private:
      void LoadSectors(SECT startPoint);
      std::vector<SECT>sectors;

};

class Storage
{
   public:
      Storage(string CompoundFile);

      //For example, this method will receive a ref to my fat system and iterate over
      //the fat array in order to read every sector. 
      LoadStrem(Fat& fat);

};

This is far simple example.

Was it helpful?

Solution

There's no syntactic sugar in C++ analogous to yield in C#. If you want to create a class, instances of which should be iterable in the same way stock STL collections are, then you have to implement an iterator for your class, expose it as ::iterator on your type, and provide begin() and end() member functions.

OTHER TIPS

You can either create an accessor function which returns a reference (or preferably const reference) to the vector, or you can create begin() and end() accessor functions which return the appropriate vector iterators.

It always hurts when you need to publish the innards of your class...

You may be able to solve it by providing algorithms as the stl does: provide a foreach function on the object's interface.

class S { 
   std::vector<int> v;

public:
   //... and some methods to populate the vector

   template< typename F > F& foreach( F& f ) { 
      return std::for_each( v.begin(), v.end(), f );
   }

};

This way, the class remains 'closed', but you have the flexibility you need. You can also add a copy function, and maybe a transform; these are the ones I most frequently need.

Let your class expose iterators.

class Fat
{
   public:
    typedef std::vector<SECT>::iterator iterator;

    iterator begin() { return sectors.begin(); }
    iterator end() { return sectors.end(); }

      Fat();
   // some code here ...

   private:
      void LoadSectors(SECT startPoint);
      std::vector<SECT>sectors;

Then the surrounding code can traverse the elements of the vector freely, through just a pair of iterators.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top