Comprender el ejemplo en la conversión lvalue-a-rvalue

Me cuesta entender cómo este código (un ejemplo del borrador del estándar C ++ 14 [conv.lval] ) invoca un comportamiento indefinido para g(false) . ¿Por qué constexpr hace que el progtwig sea válido?

Además, ¿qué significa “no accede a yn “? En ambas llamadas a g() estamos devolviendo el miembro n datos, entonces ¿por qué la última línea dice que no tiene acceso?

 struct S { int n; }; auto f() { S x { 1 }; constexpr S y { 2 }; return [&](bool b) { return (b ? y : x).n; }; } auto g = f(); int m = g(false); // undefined behavior due to access of xn outside its // lifetime int n = g(true); // OK, does not access yn 

Esto se debe a que yn no se usa y, por lo tanto, no requiere un acceso a yn las reglas para odr-use se tratan en 3.2 y dice:

Una variable x cuyo nombre aparece como una expresión potencialmente evaluada ex es odr-used a menos que al aplicar la conversión lvalue-a-rvalue (4.1) a x se obtenga una expresión constante (5.19) que no invoque ninguna función no trivial y, si x es un objeto, ex es un elemento del conjunto de resultados potenciales de una expresión e, donde la conversión lvalue-a-rvalue (4.1) se aplica a e , o e es una expresión de valor descartado

Tenga en cuenta que Ben Voigt hizo algunos comentarios útiles que aclararon esto un poco. Entonces la suposición de trabajo aquí es que x sería:

 y 

y e sería ( la expresión diferente para la que se define e se trata en el párrafo 2 de la sección 3.2 ):

 (b ? y : x).n 

y produce una expresión constante y la conversión lvalor a rvalue se aplica a la expresión e .

Dado que f produce una lambda que captura las variables locales de f por referencia x ya no es válida una vez que se realiza la llamada a f ya que x es una variable automática dentro de f . Como y es una expresión constante , actúa como si no se hubiera accedido a yn y, por lo tanto, no tenemos el mismo problema de duración.

Su ejemplo está incluido en N3939 sección 4.1 [conv.lval] y justo antes de ese ejemplo dice:

Cuando se aplica una conversión lvalue-r-valor a una expresión e, y

e incluye la siguiente viñeta a la que pertenece el examen:

la evaluación de e resultados en la evaluación de un miembro ex del conjunto de resultados potenciales de e, y ex nombra una variable x que no es usada por ex (3.2),

entonces:

el valor contenido en el objeto al que se hace referencia no se accede

Esto se aplicó al borrador del estándar C ++ 14 debido al informe de defectos 1773 .