Returning string or vector from a function

A

Alfonso Morra

Hi,

What is the recomended way of returning an STL container (e.g.
std::string, std::vector etc fom a function?

Is it by simply returning a local variable? (I doubt it)

std::string foo(const std::string& rhs) {
std::string var = rhs ;
var += " received" ;
return var ;
}

OR by pointer?

std::string *foo(const std::string& rhs) {
std::string *ps = new std::string() ;
*ps = rhs ;
*ps += " received" ; //not sure if this is legal
return ps ;
}


OR by reference ?

std::string &foo(const std::string& rhs) {
std::string var(rhs), &ref ;
var += " received" ;
ref = var ;
return ref ;
}


If anyone would kindly direct me to a web resource where I can readup on
this - I'd be grateful. I have googled for several hours and not really
found anything too useful. even the sgi STL site does not seem to cover
this basic info.
 
M

Markus Moll

Hi

Alfonso said:
What is the recomended way of returning an STL container (e.g.
std::string, std::vector etc fom a function?

I don't think there is any...
Is it by simply returning a local variable? (I doubt it)

std::string foo(const std::string& rhs) {
std::string var = rhs ;
var += " received" ;
return var ;
}

Looks reasonable...
OR by pointer?

std::string *foo(const std::string& rhs) {
std::string *ps = new std::string() ;
*ps = rhs ;
*ps += " received" ; //not sure if this is legal
(It is)
return ps ;
}

I would _never_ return (raw) pointers to newly allocated objects:

1. There can easily be memory leaks:
foo("bar");

2. It is generally a bad idea as the caller does not necessarily know
whether he's required to free the memory, how to free the memory, ...
OR by reference ?

std::string &foo(const std::string& rhs) {
std::string var(rhs), &ref ;
^ A reference needs to be bound...
var += " received" ;
ref = var ;
return ref ;
}

What you're planning to do here is quite a bad idea. You effectively want to
return a reference to a non-existent object ('var' has just gone out of
scope...)

You (might) have another option anyway:
std::string& add_received_suffix(std::string& str)
{
str += " received";
return str;
}


Markus
 
B

Ben Pope

Alfonso said:
Hi,

What is the recomended way of returning an STL container (e.g.
std::string, std::vector etc fom a function?

Is it by simply returning a local variable? (I doubt it)

std::string foo(const std::string& rhs) {
std::string var = rhs ;
var += " received" ;
return var ;
}

Returns a copy of the local, which is fine.
OR by pointer?

std::string *foo(const std::string& rhs) {
std::string *ps = new std::string() ;
*ps = rhs ;
*ps += " received" ; //not sure if this is legal
return ps ;
}

// But who deletes the memory poined to by ps?

OR by reference ?

std::string &foo(const std::string& rhs) {
std::string var(rhs), &ref ;
// Whats ref? Referecences need to point to something that exists.
var += " received" ;
ref = var ;
return ref ;
}

// Did you intend:
std::string &foo(const std::string& rhs) {
std::string var(rhs);
var += " received" ;
return var ;
}

// Return reference to local, which is now out of scope!
If anyone would kindly direct me to a web resource where I can readup on
this - I'd be grateful. I have googled for several hours and not really
found anything too useful. even the sgi STL site does not seem to cover
this basic info.

Try it:


#include <iostream>
#include <string>

std::string cFoo(const std::string& rhs) {
std::string var = rhs ;
var += " received" ;
return var ;
}

std::string *pFoo(const std::string& rhs) {
std::string *ps = new std::string() ;
*ps = rhs ;
*ps += " received" ; //not sure if this is legal
return ps ;
}

std::string &rFoo(const std::string& rhs) {
std::string var(rhs);
var += " received" ;
return var ;
}

int main(int argc, char* argv[])
{
// This works!
std::cout << cFoo("cFoo") << std::endl;
// this next line leaks the memory
std::cout << *pFoo("pFoo") << std::endl;
// This is just wrong!
std::cout << rFoo("rFoo") << std::endl;

return 0;
}

I don;t know how to test the stream state, so I'll leave that up to somebody else.

On my compiler VC 7.1, that last line doesn't output anything, and "breaks" the stream.

Ben
 
G

Gianni Mariani

Alfonso said:
Hi,

What is the recomended way of returning an STL container (e.g.
std::string, std::vector etc fom a function?

Is it by simply returning a local variable? (I doubt it)

std::string foo(const std::string& rhs) {
std::string var = rhs ;
var += " received" ;
return var ;
}

The function above is perfectly fine. The only issue may be that the
local variable (var) is copied to the destination which may be a tad
less efficient but I would not let that get in the way of using it
unless you saw a performance issue. I would just write it a little
simpler than this:

std::string foo(const std::string& rhs) {
return rhs + " received";
}

OR by pointer?

std::string *foo(const std::string& rhs) {
std::string *ps = new std::string() ;
*ps = rhs ;
*ps += " received" ; //not sure if this is legal
return ps ;
}

This is OK too but prone to errors. Use a std::auto_ptr to eliminate the
chance of errors.

std::auto_ptr said:
OR by reference ?

std::string &foo(const std::string& rhs) {
std::string var(rhs), &ref ;
var += " received" ;
ref = var ;
return ref ;
}

This is just plain bad. I'm surprised if it compiles.

a) All references must be seated (initialized) when they are created
(ref = var) is meaningless.

b) Returning a reference to a local variable is bad since the object
being referenced will be destroyed before it can be used by the caller.
If anyone would kindly direct me to a web resource where I can readup on
this - I'd be grateful. I have googled for several hours and not really
found anything too useful. even the sgi STL site does not seem to cover
this basic info.

http://www.parashift.com/c++-faq-lite/index.html
 
M

msalters

benben schreef:
May I further suggest an alternative:

void foo(vector& input_and_output);

or

template< typename OutputIterator >
void foo( OutputIterator out );

That way you don't even have to care about whether your caller
wants a vector<char> or a string. Both have back_inserters. Or,
if the caller thinks it's easier, foo could also write to a
stream_iterator.

HTH,
Michiel Salters
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top