Die Referenz existiert für die gesamte Lebensdauer von container
, aber das Objekt, auf das verwiesen wird, existiert nur für die Lebensdauer dieses Objekts. In diesem Fall haben Sie Ihre Referenz an ein temporäres Objekt mit automatischer Speicherzuweisung gebunden ("Stapelzuordnung", wenn Sie so wollen, obwohl dies keine C++ - Nomenklatur ist). Daher können Sie nicht erwarten, dass das Temporäre jenseits der Anweisung existiert, in der es geschrieben wurde (da es unmittelbar nach dem Aufruf des Konstruktors für container
aus dem Gültigkeitsbereich verschwindet). Der beste Weg, um damit umzugehen, ist eine Kopie anstelle einer Referenz zu verwenden. Da Sie sowieso eine Konstante const verwenden, wird es eine ähnliche Semantik haben.
Sie sollten Ihre Klasse neu definieren als:
template<typename T>
class container
{
public:
container(const T& first, const T& second) : first(first), second(second) {}
private:
const T first;
const T second;
};
Alternativ können Sie Ihre Objekte einen Namen, damit sie nicht gehen out of scope geben könnte:
adaptor first;
adaptor second;
container c(first,second);
Aber ich glaube nicht, Dies ist eine gute Idee, da eine Aussage wie return c
ungültig ist.
bearbeiten
Wenn Ihr Ziel ist es, Objekte zu teilen, um die Kosten für das Kopieren zu vermeiden, sollten Sie Smart-Pointer-Objekte betrachten verwenden.Zum Beispiel können wir Ihr Objekt mit Smart-Pointer neu zu definieren, wie folgt:
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;
};
Sie können dann mit:
boost::shared_ptr<const adaptor> first(new adaptor);
boost::shared_ptr<const adaptor> second(new adaptor);
container<adaptor> c(first,second);
Oder, wenn Sie lokal veränderlichem Kopie der ersten und zweiten haben wollen:
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));
Ich denke, in diesem Fall ist das temporäre an einen Funktionsaufruf-Parameter (den Aufruf des Konstruktors) wie im nächsten Satz gebunden. Ja, es ist wegen des Aliasing im ctor-Initialisierer auch an das Member gebunden, und ja, es wird bestehen bleiben, bis der Konstruktor beendet wird (länger, wenn der Full-Ausdruck, der den Konstruktoraufruf enthält, auch andere Dinge tut). Aber ich denke, die hervorgehobene Passage bezieht sich auf Dinge wie 'struct container {const & adapter a; container(): a (Adapter()) {}}; '. –
@Steve: Bei näherem Hinsehen denke ich, du hast recht - ich werde die Antwort aktualisieren (das gleiche Ergebnis aber). –