Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to return default argument's value by const reference?

Is it ok to return default argument's value by const reference like in the examples below:

https://coliru.stacked-crooked.com/a/ff76e060a007723b

#include <string>  const std::string& foo(const std::string& s = std::string("")) {     return s; }  int main() {     const std::string& s1 = foo();     std::string s2 = foo();      const std::string& s3 = foo("s");     std::string s4 = foo("s"); } 
like image 536
FrozenHeart Avatar asked Nov 01 '19 17:11

FrozenHeart


People also ask

Can a const function return a reference?

Then, no, you can't do that; in a const method you have a const this pointer (in your case it would be a const Foo * ), which means that any reference you can get to its fields1 will be a const reference, since you're accessing them through a " const path".

When should we use a const reference and why?

Pass Using Const Reference in C++ Now, we can use the const reference when we do not want any memory waste and do not change the variable's value. The above code will throw a compile error as num = num +10 is passed as a const reference.

Can you change the value of const reference?

Because the reference is a const reference the function body cannot directly change the value of that object. This has a similar property to passing by value where the function body also cannot change the value of the object that was passed in, in this case because the parameter is a copy.

When should an argument be passed by constant reference?

When you pass by const reference, you take the argument in by reference (avoiding making any copies of it), but cannot make any changes to the original object (much as would happen when you would take the parameters in by value).


1 Answers

In your code, both s1 and s3 are dangling references. s2 and s4 are ok.

In the first call, the temporary empty std::string object created from the default argument will be created in the context of the expression containing the call. Therefore, it will die at the end of the definition of s1, which leaves s1 dangling.

In the second call, the temporary std::string object is used to initialize s2, then it dies.

In the third call, the string literal "s" is used to create a temporary std::string object and that also dies at the end of the definition of s3, leaving s3 dangling.

In the fourth call, the temporary std::string object with value "s" is used to initialize s4 and then it dies.

See C++17 [class.temporary]/6.1

A temporary object bound to a reference parameter in a function call (8.2.2) persists until the completion of the full-expression containing the call.

like image 64
Brian Bi Avatar answered Sep 25 '22 08:09

Brian Bi