简体   繁体   中英

Should we use lifetime extension of a temporary in C++17 and later?

Since in C++17 it's guaranteed that the temporary created by an expression is stored in a variable assigned to:

#include <iostream>

struct Test
{
    Test()                  { std::cout << "Test()"                 << std::endl;   }
    Test(const Test &rhs)   { std::cout << "Test(const Test &rhs)"  << std::endl;   }
    Test(Test &&rhs)        { std::cout << "Test(Test &&rhs)"       << std::endl;   }

    Test &operator=(Test &&rhs)         { std::cout << "Test &operator=(Test &&rhs)"        << std::endl; return *this; }
    Test &operator=(const Test &rhs)    { std::cout << "Test &operator=(const Test &rhs)"   << std::endl; return *this; }

    ~Test() { std::cout << "~Test()" << std::endl; }
};

Test fun()
{
    return Test{};
}

int main(int argc, char** argv)
{
    auto t = fun();

    return 0;
}

Outputs:

Test()
~Test()

Deleting the assignment operators and the copy and move constructors yields the same result.

Do we still need to extend the lifetime of the temporary ('const auto &t = fun()') for any kind of optimization?

EDIT:

Test &operator=(const Test &&rhs)   { std::cout << "Test &operator=(const Test &rhs)"   << std::endl; return *this; }

Is now:

Test &operator=(const Test &rhs)   { std::cout << "Test &operator=(const Test &rhs)"   << std::endl; return *this; }

EDIT: Question clarified.

EDIT: Removed the 'language-lawyer' tag. This is a genuine question that affects much of my codebase. People normally use lifetime-extension of temporaries for performance reasons. But writing 'const auto &p =...' is longer than just write 'auto p =...', which is cleaner and expresses more the desire of the programmer.

Yes, I would still like this to work:

auto const& t = fun();

And for that to work relies upon extending the lifetime of the temporary fun() returns to match the lifetime of t . Otherwise, the Test temporary would be destroyed at end of the expression and I'd immediately have a dangling reference.

You need some way to say "give me whatever" that avoids work if the "whatever" gives you an lvalue. I don't want to do auto t = fun(); where fun() returns a T const& , that's an unnecessary copy. auto const& (or auto&& ) avoids the copy in this case, and with lifetime extension works with the prvalue case as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM