¿Volver una referencia es una buena idea?

Todos sabemos esodevolver una referencia a una variable local es una mala idea. Sin embargo, me pregunto si alguna vez es realmente una buena idea devolver una referencia y si es posible determinar algunas buenas reglas sobre cuándo o cuándo no hacerlo.

Mi problema con devolver una referencia es que la función de llamada debe preocuparse por la vida útil de un objeto que no debería ser su responsabilidad. Como un ejemplo artificial:

#include <vector>

const int& foo() {
  std::vector<int> v = {1, 2, 3, 4, 5};
  return v[0];
}

int main(int argc, const char* argv[])
{
  const int& not_valid = foo();
  return 0;
}

Aquí elvector queda fuera de alcance al final defoo, destruyendo sus contenidos e invalidando cualquier referencia a sus elementos.vector::operator[] devuelve una referencia al elemento, y así cuando esta referencia se devuelve más fuera defoo, la referencia enmain esta colgando No creo que la referencia constante extienda la vida útil aquí porque no es una referencia a un temporal.

Como dije, este es un ejemplo artificial y el escritor defoo Probablemente no sería tan tonto tratar de volverv[0] como una referencia. Sin embargo, es fácil ver cómo devolver una referencia requiere que la persona que llama se preocupe por la vida útil de un objeto que no posee. Empujando un elemento en unavector lo copia, entonces elvector Es responsable de ello. Este problema no existe para pasar un argumento de referencia porque sabe que la función se completará antes de que la persona que llama continúe y destruya el objeto.

Puedo ver que devolver una referencia permite una buena sintaxis similar a una matriz comov[0] = 5 - pero lo que es tan malo de tener una función miembro comov.set(index, value)? Al menos con esto no estaríamos exponiendo los objetos internos. Sé que también puede haber un aumento en el rendimiento al devolver una referencia, pero conRVO, Nombrado RVO (NRVO) y movimiento semántico es insignificante o inexistente.

Así que he estado tratando de imaginar en qué situaciones devolver una referencia es realmente seguro, pero no puedo entender todas las diferentes permutaciones de la semántica de propiedad que podría implicar. ¿Hay buenas reglas sobre cuándo hacer esto?

Nota: conozco una mejor manera de lidiar con la propiedad envectors es usar punteros inteligentes, pero luego surge el mismo problema con un objeto diferente: ¿quién posee el puntero inteligente?

Respuestas a la pregunta(2)

Su respuesta a la pregunta