Why doesn't the code below claim?

In this link to comp.std.C ++, Mr. Howard Hinnant shows the following code:

#include <utility> #include <cassert> struct A { A() : data_(1) {} A(A&& a) : data_(a.data_) {a.data_ = 0;} int data_; }; void g(const A&) {} void g(A&& a) {a.data_ = 0;} void h(const A&) {} void h(A&& a) {a.data_ = 0;} void f(A&& a) { g(a); // calls g(const A&) h(a); // calls h(const A&) if (true) { h(a); // calls h(A&&) (by Alexandrescu rules) } } int main() { A a; f(a); assert(a.data_ == 1); } 

Then he writes:

According to the rules of N1377, he does not approve ....

Under valid C ++ 11 rules, the code above does not compile, because lvalue a in main() does not bind to an rvalue reference. But just assuming it was compiled, as expected, for the case when this discussion occurred, I cannot understand the above statement, that is, By the N1377 rules, it does not assert. . According to previous rules, will the variable a (a.data_ = 0) be selected, since a is passed as an argument f with f (a)?

+4
source share
1 answer

In the C ++ 0x standard, the && declaration refers specifically to the r-value reference. The link in the comments is good, as well as this link, citing the 2006 version.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html

You can also find an in-depth discussion of this issue and why it matters here:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

In short, rvalue references eliminate the need for the following idiom:

 int a = 10; int b = 1000; //Now let swap them int temp = a; a = b; b = temp; 

Rvalue links allow you to use idioms that are not related to creating a temporary object, and using 50% more memory. Although, even according to the old standard, where we care about the difference between A & and A & &, if you write reasonable code, the use of rvalue links disappears, since the advantages can be easily optimized in standard code by any worthy compiler.

Honestly, I don’t know why the call to h (a) changes to an rvalue link because it is called inside the scope of the if statement.

EDIT: for the comments.

It was decided that the final use of the variable within this variable area should be the default for the rvalue version, since this is more optimal, and the theft that could be caused by such a link does not matter, since the variable will soon go beyond.

Thus, const A & version is slower than A && version. Despite the fact that the constant A & is a shorter type match, the A && version is faster and there are no dangers of its use for the last reference to the value of lvalue. Alexandrescu suggests that we use rvalue for such a “final reference”.

However, Hinnant states that (through comments), in accordance with Alexandrescu recommended modifications, the code does not do what is expected, and approval is thrown, but according to current n1377 rules with standard bindings this is not so. Debunking his proposed change to the standard.

The Hinnants example shows that this is micro-optimization, and that the rule should be much more consific than Alexandrescu suggests. And this is because we can also pass lvalues ​​by reference, times when you can safely use such rvalue links, ultimately - only once to declare a variable, at best, a little optimization.

+1
source

Source: https://habr.com/ru/post/1485487/


All Articles