Miembro de referencia agregado y vida útil temporal

Dado este ejemplo de código, ¿cuáles son las reglas con respecto a la vida útil de la cadena temporal que se pasa aS.

struct S
{
    // [1] S(const std::string& str) : str_{str} {}
    // [2] S(S&& other) : str_{std::move(other).str} {}

    const std::string& str_;
};

S a{"foo"}; // direct-initialization

auto b = S{"bar"}; // copy-initialization with rvalue

std::string foobar{"foobar"};
auto c = S{foobar}; // copy-initialization with lvalue

const std::string& baz = "baz";
auto d = S{baz}; // copy-initialization with lvalue-ref to temporary

De acuerdo con el estándar:

N4140 12.2 p5.1 (eliminado en N4296)

Un enlace temporal a un miembro de referencia en un ctor-initializer del constructor (12.6.2) persiste hasta que el constructor sale.

N4296 12.6.2 p8

Una expresión temporal vinculada a un miembro de referencia en un mem-initializer está mal formada.

Entonces tener un constructor definido por el usuario como[1] Definitivamente no es lo que queremos. Incluso se supone que está mal formado en el último C ++ 14 (¿o no?) Ni gcc ni clang lo advirtieron.
¿Cambia con la inicialización agregada directa? Parece que en ese caso, la vida útil temporal se extiende.

Ahora con respecto a la inicialización de copia,Constructor de movimiento predeterminado y miembros de referencia Establece que[2] se genera implícitamente Dado el hecho de que el movimiento podría eludirse, ¿se aplica la misma regla al constructor de movimiento generado implícitamente?

Cual dea, b, c, d tiene una referencia valida?

Respuestas a la pregunta(1)

Su respuesta a la pregunta