Returning containers

A

Andrew Ward

Hi,

A third-party container library I use implements its containers using
copy-on-write semantics, making it efficient to return an instance of
the container by value from a function. For example:

ThirdPartyContainer<MyClass> foo();

If I want to refactor this function to use std::list I could do this:

std::list<MyClass> foo();

Which as far as I know could be either efficient or inefficient
depending on the library implementation.

What I wanted to know is what technique other people use? I can think of
a few other ways of writing the function:

void foo(std::list<MyClass> * toFill);
or
void foo(std::list<MyClass> & toFill);
or
std::auto_ptr<std::list<MyClass> > foo();

None of which are as easy to use as the return by value approach.
 
R

Rolf Magnus

Andrew said:
Hi,

A third-party container library I use implements its containers using
copy-on-write semantics, making it efficient to return an instance of
the container by value from a function. For example:

ThirdPartyContainer<MyClass> foo();

If I want to refactor this function to use std::list I could do this:

std::list<MyClass> foo();

Which as far as I know could be either efficient or inefficient
depending on the library implementation.

And depending on the implementation of the C++ compiler itself. A good one
can optimize the copy away.
What I wanted to know is what technique other people use? I can think of
a few other ways of writing the function:

void foo(std::list<MyClass> * toFill);
or
void foo(std::list<MyClass> & toFill);
or
std::auto_ptr<std::list<MyClass> > foo();

None of which are as easy to use as the return by value approach.

The typical way used by the C++ standard library is to work with iterators
instead of containers.
 
A

Andrew Ward

Rolf said:
Andrew Ward wrote:




And depending on the implementation of the C++ compiler itself. A good one
can optimize the copy away.




The typical way used by the C++ standard library is to work with iterators
instead of containers.

That's fine if the collection is a member of some object, then I could
provide member functions:
std::list<MyClass>::const_iterator begin() const;
std::list<MyClass>::const_iterator end() const;

However quite often the called function will be generating the
collection data.

For example:
MyPeopleDatabase d;
std::list<People> allPeople() const;

How could that be done with iterators? I cannot do:
std::pair<std::list<People>::const_iterator,
std::list<People>::const_iterator> allPeople() const;

As there is no where I want to persist the collection inside 'd'.
 
H

Howard

Andrew Ward said:
Hi,

A third-party container library I use implements its containers using
copy-on-write semantics, making it efficient to return an instance of the
container by value from a function. For example:

ThirdPartyContainer<MyClass> foo();

If I want to refactor this function to use std::list I could do this:

std::list<MyClass> foo();

Which as far as I know could be either efficient or inefficient depending
on the library implementation.

What I wanted to know is what technique other people use? I can think of a
few other ways of writing the function:

void foo(std::list<MyClass> * toFill);
or
void foo(std::list<MyClass> & toFill);
or
std::auto_ptr<std::list<MyClass> > foo();

None of which are as easy to use as the return by value approach.

I prefer the approach of passing a reference. This is the way I often
handle such problems, regardless of what kind of container or object it is
I'm talking about. Even plain C-style arrays are often best handled like
this (assuming you're stuck using them in the first place), where you pass
the function a pointer to the first element (and a count of the elements),
and let them go to town on it.

I think of it like this: I'm giving someone a blank form which they need to
fill out. This leaves me in complete charge of the lifetime of the "form",
from its construction through its destruction, and all I ask of others
(i.e., functions), is that they use the form I give them, whether that's
filling it out, editing it, or building some kind of report from it.

This approach means I never get confused about who "owns" a dynamically
allocated object, and cleanup is much easier to handle.

-Howard
 

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
473,999
Messages
2,570,246
Members
46,839
Latest member
MartinaBur

Latest Threads

Top