Domanda

Si consideri il seguente.

#include <string>
using std::string;

string middle_name () {
    return "Jaan";
}

int main ()
{
    string&& danger = middle_name();   // ?!
    return 0;
}

Questa non calcola nulla, ma si compila senza errori e dimostra una cosa che mi confonde:? danger è un riferimento penzoloni, non è vero

È stato utile?

Soluzione

  

Do riferimenti rvalue permettono penzoloni riferimenti?

Se si intende "E 'possibile creare penzoloni riferimenti rvalue", quindi la risposta è sì. Il vostro esempio, tuttavia,

string middle_name () {
    return "Jaan";
}

int main()
{
    string&& nodanger = middle_name();   // OK.
    // The life-time of the temporary is extended
    // to the life-time of the reference.
    return 0;
}

è perfettamente bene. La stessa regola si applica qui che fa questo esempio (articolo di Herb Sutter) sicuro pure. Se si inizializza un riferimento con un puro rvalue , il tempo di vita dell'oggetto tempoary ottiene esteso alla vita in tempo di riferimento. È ancora possibile produrre penzoloni riferimenti, però. Ad esempio, questo non è più sicuro:

int main()
{
    string&& danger = std::move(middle_name());  // dangling reference !
    return 0;
}

A causa std::move restituisce un string&& (che è non puro rvalue ) la regola che si estende dagli anni temporanei tempo di vita non si applica. Qui, std::move restituisce un cosiddetto xValue . Un xValue è solo un riferimento rvalue senza nome. Come tale potrebbe riferirsi a qualsiasi cosa ed è fondamentalmente impossibile indovinare ciò che un riferimento restituito si riferisce a senza guardare implementazione della funzione.

Altri suggerimenti

riferimenti rvalue si legano ai rvalues. Un rvalue è o un prvalue o un xValue [ spiegazione ]. Il legame con l'ex non crea mai un riferimento penzoloni, il legame con il secondo potrebbe. Ecco perché è generalmente una cattiva idea di scegliere T&& come tipo di ritorno di una funzione. std::move è un'eccezione a questa regola.

T&  lvalue();
T   prvalue();
T&& xvalue();

T&& does_not_compile = lvalue();
T&& well_behaved = prvalue();
T&& problematic = xvalue();
  

danger è un riferimento penzoloni, non è vero?

Non più di quanto se si fosse usato un const &:. danger assume la proprietà del rvalue

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top