Skip to main content
compacting
Source Link
Daniel Jour
  • 16.2k
  • 2
  • 40
  • 68

So itits lifetime must be extended, except when:

Not our case.

Not our case.

Not our case.

Not our case.

So, ourOur case doesn't fit theany 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:

  1. 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 ...

  1. 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.

So it must be extended, except when:

Not our case.

Not our case.

Not our case.

Not our case.

So, our case doesn't fit the exceptions, thus it must follow the rule. g++ is wrong here.

So its lifetime must be extended, except when:

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:

  1. 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 ...

  1. 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.

Source Link
Daniel Jour
  • 16.2k
  • 2
  • 40
  • 68

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 it must be extended, except when:

A temporary bound to a reference member in a constructor’s ctor-initializer [..]

Not our case.

A temporary bound to a reference parameter in a function call [..]

Not our case.

The lifetime of a temporary bound to the returned value in a function return statement [..]

Not our case.

A temporary bound to a reference in a new-initializer [..]

Not our case.

So, our case doesn't fit the exceptions, thus it must follow the rule. g++ is wrong here.