开发者

Do compilers automatically use move semantics when a movable object is used for the last time?

开发者 https://www.devze.com 2023-03-07 11:06 出处:网络
I\'ve been studying rvalue references lately and came to a conclusion that it\'s quite advantageous t开发者_如何学运维o use pass-by-value everywhere where complete copy of an object will be made (for

I've been studying rvalue references lately and came to a conclusion that it's quite advantageous t开发者_如何学运维o use pass-by-value everywhere where complete copy of an object will be made (for complete justification see e.g. How to reduce redundant code when adding rvalue reference operator overloads? and Want speed? Pass by value!), because the compiler can automatically optimize a copy away in cases such as f(std::move(a));, where f is defined as void f(A a);.

One negative consequence of pass-by-value-everywhere is that all the code becomes littered with std::move even in simple cases such as:

void Object::value(A a) 
{
    value_ = std::move(a);
}

Obviously, if I wrote only the following:

void Object::value(A a) 
{
    value_ = a;
}

it shouldn't be hard for the compiler to recognize that a is near the end of its lifetime even without the hint and not to penalize me with additional copy. In fact, the compiler should be able to recognize this even in complex functions.

The questions:

  1. Is this optimization allowed by the C++0x Standard?

  2. Do the compilers employ it? Even in complex cases, i.e. the function consists from more than one line?

  3. How reliable is this optimization, i.e. can I expect the compiler to utilize it as much as I expect the compiler to apply Return Value Optimization?


Is this optimization allowed by the C++0x Standard?

No.

Do the compilers employ it? Even in complex cases, i.e. the function consists from more than one line?

No.

How reliable is this optimization, i.e. can I expect the compiler to utilize it as much as I expect the compiler to apply Return Value Optimization?

You should decorate A(const A&) and A(A&&) with print statements and run test cases of interest to you. Don't forget to test lvalue arguments if those use cases are part of your design.

The correct answers will depend upon how expensive the copy and move of A are,how many arguments Object::value actually has, and how much code repetition you're willing to put up with.

Finally, be very suspicious of any guideline that contains words like "always" or "everywhere". E.g. I use goto every once in a while. But other programmers have words like "never" associated with goto. But every once in a while, you can't beat a goto for both speed and clarity.

There will be times you should favor a pair of foo(const A&) foo(A&&) over foo(A). And times you won't. Your experiments with decorated copy and move members will guide you.

0

精彩评论

暂无评论...
验证码 换一张
取 消