The best way to return std :: string, which is local to the function

In C ++, what is the best way to return a local std :: string function from a function?

std::string MyFunc() { std::string mystring("test"); return mystring; } std::string ret = MyFunc(); // ret has no value because mystring has already gone out of scope...??? 
+47
c ++ return-value
Oct. 20 2018-10-10
source share
6 answers

No. It is not true. Even if mystring gone out of scope and destroyed, ret has a copy of mystring, because the MyFunc function returns a value.

+64
Oct. 20 '10 at 10:45
source share

There will be a problem if your code looks like:

 std::string& MyFunc() { std::string mystring("test"); return mystring; } 

So, as you wrote it, everything is in order. Only one piece of advice: if you can build such a line, I mean - you can do it on one line, sometimes it’s better to do it like this:

 std::string MyFunc() { return "test"; } 

Or, if it is more "complicated", for example:

 std::string MyFunct( const std::string& s1, const std::string& s2, const char* szOtherString ) { return std::string( "test1" ) + s1 + std::string( szOtherString ) + s2; } 

This will give your compiler a hint to do a lot of optimization so that it can make one smaller copy of your string (RVO).

+18
Oct 20 '10 at 11:09
source share

You tried? The string is copied when it is returned. It’s good that the official line, in fact the copy, is probably optimized, but in any case it is safe to use.

+5
Oct 20 2018-10-10
source share

As already mentioned, std :: string is copied. Thus, even the original local variable went beyond the scope, the caller receives a copy of std :: string.

I think reading on RVO can completely clear your confusion. In this case, it is definitely referred to as NRVO (Named RVO), but the spirit is the same.

Reading Bonuses: The problem with using RVO is that it is not the most flexible thing in the world. One of the big bugs of C ++ 0x is rvalue links that intend to solve this problem.

+5
Oct 20 2018-10-10
source share

Well, ret will have a mystring value after MyFunc (). If the result is returned by value, a temporary object is created by copying the local one.

As for me, there are some interesting details about the topic in these sections of the C ++ FAQ Lite .

+3
Oct. 20 2018-10-10
source share

It depends on the use case. If the instance should be responsible for the string, the sting should be returned with a const reference. The problem is what to do if there is no object to return. With pointers, an invalid object can be signaled using 0. Such a "null object" can also be used with references (for example, NullString in a code snippet). Because of a better way to supply an invalid return value, exceptions are thrown.

Another use case is if string responsibility is transferred to the caller. In this case, use auto_ptr. The code below shows all of these use cases.

 #include <string> #include <memory> //auto_ptr #include <iostream> using std::string; using std::auto_ptr; using std::cout; using std::endl; static const string NullString("NullString\0"); ///// Use-Case: GETTER ////////////////// //assume, string should be found in a list // and returned by const reference //Variant 1: Pseudo null object const string & getString( bool exists ) { //string found in list if( exists ) { static const string str("String from list"); return str; } //string is NOT found in list return NullString; } //Variant 2: exception const string & getStringEx( bool available ) { //string found in list if( available ) { static const string str("String from list"); return str; } throw 0; //no valid value to return } ///// Use-Case: CREATER ///////////////// auto_ptr<string> createString( bool ok ) { if( ok ){ return auto_ptr<string>(new string("A piece of big text")); }else{ return auto_ptr<string>(); } } int main(){ bool ok=true, fail=false; string str; str = getString( ok ); cout << str << ", IsNull:"<<( str == NullString )<<endl; str = getString( fail ); cout << str << ", IsNull:"<<( str == NullString )<<endl; try{ str = getStringEx( ok ); cout << str <<endl; str = getStringEx( fail ); cout << str <<endl; //line won't be reached because of ex. } catch (...) { cout << "EX: no valid value to return available\n"; } auto_ptr<string> ptext = createString( ok ); if ( ptext.get() ){ cout << *ptext << endl; } else { cout << " Error, no text available"<<endl; } ptext = createString( fail ); if ( ptext.get() ){ cout << *ptext << endl; } else { cout << " Error, no text available"<<endl; } return 0; } 

Regards, Valentine Heinitz

+2
Oct. 20 2018-10-10
source share



All Articles