La referencia existirá durante toda la vida útil de container
, pero el objeto al que se hace referencia existirá solo durante el tiempo de vida de ese objeto. En este caso, ha vinculado su referencia a un objeto temporal con asignación de almacenamiento automático ("asignación de pila", si así lo desea, aunque esa no es la nomenclatura de C++). Por lo tanto, no puede esperar que el temporal exista más allá de la declaración en la que se escribió (ya que sale del alcance inmediatamente después de la llamada al constructor para container
). La mejor manera de lidiar con esto es usar una copia, en lugar de una referencia. Ya que está usando una referencia constante, de todos modos, tendrá una semántica similar.
Deberá volver a definir su clase como:
template<typename T>
class container
{
public:
container(const T& first, const T& second) : first(first), second(second) {}
private:
const T first;
const T second;
};
Como alternativa, puede dar a sus objetos un nombre para evitar que se salgan de alcance:
adaptor first;
adaptor second;
container c(first,second);
Sin embargo, no creo esta es una buena idea, ya que una declaración como return c
no es válida.
Editar
Si su objetivo es compartir objetos con el fin de evitar el costo de la copia, entonces usted debe considerar el uso de objetos puntero inteligente.Por ejemplo, podemos redefinir su objeto utilizando punteros inteligentes de la siguiente manera:
template<typename T>
class container
{
public:
container(const boost::shared_ptr<const T>& first, const boost::shared_ptr<const T>& second) : first(first), second(second) {}
private:
boost::shared_ptr<const T> first;
boost::shared_ptr<const T> second;
};
continuación, puede utilizar:
boost::shared_ptr<const adaptor> first(new adaptor);
boost::shared_ptr<const adaptor> second(new adaptor);
container<adaptor> c(first,second);
O, si usted quiere tener copias mutables de primer y segundo nivel local:
boost::shared_ptr<adaptor> first(new adaptor);
boost::shared_ptr<adaptor> second(new adaptor);
container<adaptor> c(boost::const_pointer_cast<const adaptor>(first),boost::const_pointer_cast<const adaptor>(second));
Creo que, en este caso, el temporal está vinculado a un parámetro de llamada de función (la llamada al constructor) como en la siguiente oración. Sí, también está vinculado al miembro debido al aliasing en el inicializador de ctor, y sí, persistirá hasta que el constructor salga (más tiempo, de hecho, si la expresión completa que contiene la llamada del constructor también hace otras cosas). Pero creo que el pasaje resaltado se refiere a cosas como 'struct container {const & adapter a; contenedor(): a (adaptador()) {}}; '. –
@Steve: en una mirada más cercana, creo que tienes razón, actualizaré la respuesta (aunque el mismo resultado). –