tags:

views:

234

answers:

4

I have class A, that contains std::vector and I would like to give an access to the vector from outside class A.

The first thing that came to my mind is to make a get function that returns iterator to the vector, but walk through the vector I will need two iterators (begin and end).

I was wondering is there any way (technique or patters) to iterate whole vector with only one iterator? Or maybe some other way to get access to vector, of course without using vector as return value :)

A: 

The STL introduced the idiom of using two vectors for describing a range. Since then begin() and end() are the getters. The advantage of this is that a simple pair of pointers into a C array can be used as perfect iterators. The disadvantage is that you need to carry around two objects. C++1x will, AFAIK, introduce a range concept to somewhat ease the latter.

sbi
Basically, I want to read data from vector.
+2  A: 

It seems potentially unwise to give that much access to the vector, but if you're going to why not just return a pointer or reference to the vector? (Returning the vector itself is going to be potentially expensive.) Alternately, return a std::pair<> of iterators.

An iterator is just an indicator for one object; for example, a pointer can be a perfectly good random-access iterator. It doesn't carry information about what sort of container the object is in.

David Thornley
That seems against the common idiom which dictates `begin()` and `end()` members to get access to the underlying container.
sbi
By giving out only iterators, you don't allow changes to the container itself (adding / removing elements). Besides you can only give out `const_iterators` for read-only access. Whether that is right thing to do depends on what the class does: may-be it only wants to control how insertions / erasures occur?
UncleBens
I agree; if you must provide access to the vector, just return a reference. Make it a const reference if you want to ensure read-only access.
Charles Salvia
I see only disadvantages to handing out pointers or references to container itself - the OP already considered providing only iterators, thus it seems he doesn't want to change the container. Why provide access to it then?
Georg Fritzsche
+2  A: 

Why not add both a begin() and end() function to your class that simply return v.begin(); and return v.end();? (Assuming v is your vector.)

class MyVectorWrapper
{
public:
  // Give yourself the freedom to change underlying types later on:
  typedef vector<int>::const_iterator const_iterator;

  // Since you only want to read, only provide the const versions of begin/end:
  const_iterator begin() const { return v.begin(); }
  const_iterator end() const { return v.end(); }

private:
  // the underlying vector:
  vector<int> v;
}

Then you could iterate through your class like any other:

MyVectorWrapper myV;
for (MyVectorWrapper::const_iterator iter = myV.begin(); iter != myV.end(); ++i)
{
  // do something with iter:
}
Bill
A: 

It sounds like what you need to accomplish will be potential violation of the so called Law of Demeter. This law is often an overkill, but oftentimes it is reasonable to obey it. Although you may grant read-only access by giving out only const-iterators you are still at risk that your iterators will get invalidated (easily with vectors) without third party knowing it. As you can never predict how your program will evolve over-time it is better to avoid providing features that can be misused.
Common motto: make your class interface easy to use and hard to misuse. The second part is important for overall product quality.

BostonLogan