Move o optimización de valor de retorno con nombre (NRVO)?

Dejemos que tengamos el siguiente código:

std::vector<int> f()
{
  std::vector<int> y;
  ...
  return y;
} 

std::vector<int> x = ...
x = f();

arece que el compilador tiene dos enfoques aquí:

(a) NRVO: Destruya x, luego construya f () en lugar de x.
(b) Mover: Construye f () en el espacio temporal, mueve f () a x, destruye f ().

El compilador es libre de usar cualquiera de los enfoques, de acuerdo con el estándar?

Respuestas a la pregunta(1)

Su respuesta a la pregunta