const reference default-value
Solution 1
You can't take a non-const reference to a temporary like foo2 does.
Notice that this isn't specifically default parameters. You get the same error for function variables: http://ideone.com/g7Tf7L
#include <string>
using std::string;
#include <iostream>
using std::cout; using std::endl;
int main()
{
string s1 = string("s1"); // OK, copy it
const string& s2 = string("s2"); // OK, const reference to it
string& s3 = string("s3"); // ERROR! non-const reference not allowed!
cout
<< s1 << ", "
<< s2 << ", "
<< s3 << endl;
return 0;
}
When you take a const reference to a temporary, the lifetime of the temporary is extended to the lifetime of the reference (§12.2, quoted from my copy of C++11 draft n3337):
There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.
...
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
- A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
- A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
- The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
- A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.
Solution 2
It may come as a surprise to you, but you can bind the value of a temporary expression to a constant reference, and the lifetime of the expression is extended to that of the reference. But you cannot do this with a non-constant (lvalue) reference.
aiao
Embedded Software Engineer. Areas of expertise: AUTOSAR, Linux, Yocto, information security, dynamic controls and drones.
Updated on January 31, 2020Comments
-
aiao over 4 years
Possible Duplicate:
how to initialize function arguments that are classes with default value#include <string> void foo1(const std::string& s = std::string()); void foo2(std::string& s = std::string()); void foo3(const std::string s = std::string()); void foo4(std::string s = std::string());
error at foo2(): default argument for ‘std::string& s’ has type ‘std::string {aka std::basic_string<char>}’
I understand the compiler's point, but I don't get how this does not apply to
foo1()
as well. -
aiao over 11 years1. Can you elaborate (or direct me somewhere), why not, but ok to take for const reference 2. what is the life time of this temporary?
-
David Schwartz over 11 yearsConsider
void myAbs(int &j) { if (j < 0) j = -j; }
short q; ... myAbs(q);
. This would (if it were allowed) create a temporary int, set it to its absolute value, then destroy it leavingq
unchanged. Yuck. Theconst
promises the compiler you're not going to do that. -
aiao over 11 yearswhat is the life time for this temporary in
foo3()
andfoo4()
? -
Johannes Schaub - litb over 11 years@aiao the lifetime in all cases is that of the calling full expressions evaluation time. a reference function parameter does not lengthen the lifetime of an argument, nor does it shorten it.
-
Remy Lebeau over 11 yearsIn C++11, you can haave a non-const reference to a temporary if you use an rvalue reference.
foo2()
in this example is using an lvalue reference instead. -
Kerrek SB over 11 years@aiao: The lifetime of the temporary is the lifetime of the full-expression in which it occurs. It's actually the same for
foo1
andfoo3
, but iffoo3
the temporary is only used to copy-initialize the variables
. -
jaques-sam about 4 yearsDoes
foo1
work when called from another dynamic library? I hear a colleague had trouble with this, but can't confirm. -
dragonxlwang over 3 yearsand to be more precise, only local const reference can prolongs the lifetime of a temporary, with exceptions. Class initialization of const reference does not do so. stackoverflow.com/questions/2784262/…