Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
542 views
in Technique[技术] by (71.8m points)

c++11 - R-value in C++0x

Rvalues IMHO are great improvement in C++, but at the beginning they're quite confusing. Please look at code below:

#include <string>

std::string && foo ()
{
    std::string message ("Hello!");
    
    return std::move (message);
}

void bar (const std::string &message2)
{
    if (message2 == "Bye Bye!")
        return;
}

int main ()
{
    bar (foo ());
}

Reference message2 is last owner of original message object returned by foo(), right?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

No, it's not right. You fell for the usual trap one make when discovering rvalue reference, as did Motti in the other answer! (And I did this mistake too, in my earlier test with rvalue reference.)

If you don't want to shoot yourself in the foot when dealing with rvalue reference, internalize this:

In most case, a function returning an rvalue reference is as foolish as a function returning a normal reference.

Because rvalue references are... references! So if you return a reference - rvalue or not - to message, you return a reference to an object that was just destroyed, because it went out of scope, so you return a dangling reference. It's a bug.

Also, don't write return std::move(message) because the compiler knows already that message need not be copied nor moved, but constructed directly in the memory location at the call site, so there is no need to recast it with std::move. And actually, writing return std::move(something) can prevent optimization.

So, the correct and most efficient way is:

#include <string>
std::string foo (void)
{
    std::string message ("Hello!");
    return message;
}

void bar (const std::string& message2)
{
    if (message2 == "Bye Bye!")
        return;
}

int main ()
{
    bar (foo());
}

Good old C++03 :)
Because NRVO kicks in and there is no copy, no move, only one construction.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...