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?)

source to share

2 answers

The function func()

returns a std::string

prvalue. The constructor used to build std::string


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();




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


". 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.



All Articles