Return by value in rvalue reference

I am looking into rvalue references and I have doubts about the following code:

string func() {
    return "Paul";
}

int main()
{
    string&& nodanger = func();
    // The lifetime of the temporary is extended
    // to the life-time of the reference.
    return 0;
}

      

Question: what is returned func()

?

I believe this is happening:

  • func returns prvalue "Paul" (is it const char * due to rvalue-> pointer conversion?)
  • the string object is implicitly constructed (which ctor is used?)
  • binds to "nodanger" due to link folding rules (does this behave differently than a string and a normal link?)
+3


source to share


2 answers


The function func()

returns a std::string

prvalue. The constructor used to build std::string

is

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

      

This prvalue is bound to the rvalue reference nodanger

, which extends the lifetime to match the reference itself. The link does not come into play here.



does it behave differently than a normal link string&

?

The code will not compile if nodanger

was string&

because you can not communicate with links rvalues const lvalue. The lifespan extension behavior in your example is identical to the following case

std::string const& nodanger = func();

      

+7


source


There is definitely a lot of confusion here. I suppose there middle_name()

should be func()

.

Question: what does func () function return?

It returns a string

(which I will count std::string

). This return object is initialized with an expression of "Paul"

type "array of 5 const

char

". The constructor used is as follows:

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

      

To call this function, a string literal must undergo an implicit conversion between strings (taking us from const char[5]

to const char*

.



An expression func()

is a prvalue expression (a subset of rvalue expressions) because it returns a value. Here's how the standard defines it:

A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference for a function type, an xvalue if the result type is an rvalue reference for an object type, and a prvalue otherwise.

It doesn't make sense to say that "returns a prvalue". "Prvalue" is not an object or type. This is a category of expression. The expression that calls func

is prvalue.

An rvalue reference binds to an object std::string

that was returned from a function. There are no links to crumbling here. If the reference was an lvalue reference instead, your code will not compile because a non- const

lvalue reference can not bind to an rvalue expression.

+2


source







All Articles