Search code examples
c++c++14lifetimervo

C++ standard: return by copy to initialize a reference without RVO: is there any copy?


Let's consider the next sample:

struct big_type {};

// Return by copy
auto factory() { return big_type{}; }

void any_scope_or_function() {
    big_type&& lifetime_extended = factory();
}

Under the assumption RVO is forbidden or not present at all and in any manner, will or can big_type() be copied? Or will the reference be directly bound to the temporary constructed within the return statement?

I want to be sure the big_type destructor is called only once when any_scope_or_function ends.

I use C++14, in case some behaviour has changed between standard's versions.


Solution

  • Assuming there is no RVO/copy elison then in

    auto factory() { return big_type{}; }
    

    big_type{} is going to create a temporary big_type. This object is then going to be used to copy initialize the object the function returns. This means that the object you make in the function is going to be constructed and destructed.

    With

    big_type&& lifetime_extended = factory();
    

    the rvalue reference will extend the lifetime of the functions return so we will see in total a default constructor call, a copy/move constructor call, and two destructor calls.

    Now, if we change

    auto factory() { return big_type{}; }
    

    to

    big_type factory() { return {}; }
    

    then we are no longer creating a object in factory. the return object is directly initialized with {} giving us in total a default constructor call and a destructor call