Move constructor suppressed by comma operator

This program:

#include <iostream> struct T { T() {} T(const T &) { std::cout << "copy constructor "; } T(T &&) { std::cout << "move constructor "; } }; int main() { ([](T t) -> T { return t; })({}); std::cout << '\n'; ([](T t) -> T { return void(), t; })({}); std::cout << '\n'; ([](T t) -> T { return void(), std::move(t); })({}); std::cout << '\n'; } 

when compiling with gcc-4.7.1 outputs ( link ):

 move constructor copy constructor move constructor 

Why does the comma operator have this effect? The standard says:

5.18 Comma operator [expr.comma]

1 - [...] The type and value of the result is the type and value of the right operand; the result has the same category of values โ€‹โ€‹as its right operand [...]. If the value of the correct operand is temporary, the result is temporary.

Am I missing something that allows the comma operator to influence the semantics of the program, or is it a bug in gcc?

+13
c ++ c ++ 11 move-semantics return comma-operator
Sep 05 '12 at 19:05
source share
2 answers

Auto move based on copy right:

ยง12.8 [class.copy] p32

When the criteria for performing the copy operation are fulfilled or are fulfilled, except for the fact that the source object is a parameter of the function, and the object to be copied is determined by the value of lvalue, the overload resolution to select the constructor for the copy is first executed as if the object was designated rvalue. [...]

And elision copying is in turn allowed when the returned expressions are the name of an automatic object.

ยง12.8 [class.copy] p31

in the return in a function with the type of the returned class , when the expression is the name of a non-volatile automatic object (except for the function or catch-clause parameter) with the same cv-unqualified type as the returned type of the function, the copy / move operation can be omitted by constructing the automatic object directly to the return value of the function

With the comma operator entered, the expression is no longer the name of the automatic object, but only a reference to it, which suppresses copying.

+14
Sep 05 '12 at 19:20
source share

t is a local variable with a name, and therefore lvalue. The comma operator behaves as documented.

Rather, you should ask why return t; allows t to link to an rvalue reference - this is real magic.

+8
Sep 05 '12 at 19:19
source share



All Articles