I would argue for a bug in g++, because, quoting draft N3242, §12.2/5:
The second context is when a reference is bound to a temporary. The temporary to which the reference is
bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
So its lifetime must be extended, except when:
A temporary bound to a reference member in a constructor’s ctor-initializer [..]
A temporary bound to a reference parameter in a function call [..]
The lifetime of a temporary bound to the returned value in a function return statement [..]
A temporary bound to a reference in a new-initializer
[..]
Our case doesn't fit any of these exceptions, thus it must follow the rule. I'd say g++ is wrong here.
Then, regarding the quote aschepler brought up from the same draft §8.5.3/5 (emphasis mine):
A reference to type "cv1 T1
" is initialized by an expression of type "cv2 T2
" as follows:
If the reference is an lvalue reference and the initializer expression
a. is an lvalue (but is not a bit-field) and "cv1 T1
" is reference-compatible with "cv2 T2
", or
b. has a class type ...
then ...
Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const
), or the reference shall be an rvalue reference.
a. If the initializer expression
i. is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1
" is reference-compatible with "cv2 T2
", or
ii. has a class type ...
then the reference is bound to the value of the initializer expression in the first case....
b. Otherwise, a temporary of type "cv1 T1
" is created and initialized from the initializer expression using the rules for a non-reference copy-initialization (8.5). The reference is then bound to the temporary.
Looking at what an xvalue is, this time quoting http://en.cppreference.com/w/cpp/language/value_category ...
An xvalue ("expiring value") expression is [..]
a.m
, the member of object expression, where a is an rvalue and m is a non-static data member of non-reference type;
... the expression center().x
should be an xvalue, thus case 2a from §8.5.3/5 applies (and not the copy). I'll stay with my suggestion: g++ is wrong.