By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,116 Members | 1,244 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,116 IT Pros & Developers. It's quick & easy.

Returning string or vector from a function

P: n/a
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.

Jul 23 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Hi

Alfonso Morra wrote:
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

Jul 23 '05 #2

P: n/a
Alfonso Morra wrote:
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
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #3

P: n/a
Alfonso Morra wrote:
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<std::string> foo(const std::string& rhs)


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
Jul 23 '05 #4

P: n/a
May I further suggest an alternative:

void foo(vector& input_and_output);


Jul 23 '05 #5

P: n/a


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

Jul 23 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.