best practice for returning elements from a container

J

Joe Van Dyk

Hi,

I have a class that looks like:

class ResultSet
Element* getNext();
// more

Now, I'd like to allow syntax similar to

while( i can grab stuff from the result set)
do something with the next element

What should ResultSet::getNext() return? A pointer to the next result and
NULL if there's no more results? A reference to the next element and
throw an exception if the user tries to getNext() when there's nothing
left? A smart pointer?

Btw, the user shouldn't be able to modify the returned Element at all.

Thanks,
Joe
 
V

Victor Bazarov

Joe said:
I have a class that looks like:

class ResultSet
Element* getNext();
// more

Now, I'd like to allow syntax similar to

while( i can grab stuff from the result set)
do something with the next element

What should ResultSet::getNext() return? A pointer to the next
result and NULL if there's no more results? A reference to the next
element and throw an exception if the user tries to getNext() when
there's nothing left? A smart pointer?

Btw, the user shouldn't be able to modify the returned Element at all.

I don't know of the best practice, but at some point something similar to

ResultSet resultset;
/// ...
ResultSet::Enumerator enumerator(resultset);
while (!enumerator.atEnd()) {
Element const* pEl = enumerator.getNext(); // returns and moves
...
}

worked for me...

V
 
D

Daniel T.

Joe Van Dyk said:
Hi,

I have a class that looks like:

class ResultSet
Element* getNext();
// more

Now, I'd like to allow syntax similar to

while( i can grab stuff from the result set)
do something with the next element

What should ResultSet::getNext() return? A pointer to the next result and
NULL if there's no more results? A reference to the next element and
throw an exception if the user tries to getNext() when there's nothing
left? A smart pointer?

There are several ways to do this.

class ResultSet {
public:
template < typename Op >
void doToAll( Op fn ) {
// iterate through each element calling fn( e ) on them
}
};

The caller would:

struct operation {
void operator()( const Element& e ) {
// do whatever on 'e'
}
};

void code( ResultSet& r ) {
r.doToAll( operation() );
}

Another...

class ResultSet {
public:
const Element& current() const;
bool done() const;
void advance();
void reset();
};

void code( const ResultSet& r )
{
for ( r.reset(); !r.done(); r.advance() ) {
// do whatever on 'r.current()'
}
}

And of course, there is the way the standard does it...
Btw, the user shouldn't be able to modify the returned Element at all.

In that case, whatever is returned should be const.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top