6

Diciamo che ho una funzione:I valori di ritorno saranno passati dal riferimento di rvalue in C++ 0x?

typedef std::vector<int> VecType; 
VecType randomVector(); 

int processing() 
{ 
    VecType v = randomVector(); 
    return std::accumulate(v.begin(), v.end(), 0); 
} 

non C++ 0x specificamente dire la copia spuria sarà scongiurato dal valore di ritorno di randomVector? O un compilatore dovrebbe implementare il RVO? A me sembra che il valore randomVector() debba essere trattato come un valore rvalore, e quindi il costruttore di v dovrebbe essere chiamato, ma non sono completamente sicuro che sia vero.

+0

Non una buona domanda, IMHO. Lo standard non può indicare utilmente cosa può fare un'implementazione, solo ciò che DEVE fare. –

+0

In realtà nell'esempio che avevi dato l'ottimizzazione del valore di ritorno viene eseguita dalla maggior parte dei compilatori ... Quindi è efficace senza valore. Anche il valore di rvalue è più importante per il passaggio degli argomenti alle funzioni. – Artyom

+0

Il titolo della domanda è un po 'fuorviante. La tua funzione restituisce un valore e non un riferimento. Ma un riferimento di rvalue può legarsi ad esso che è ciò che accade nel caso in cui copy elision non può essere eseguita per qualche motivo e il tipo ha un move-constructor (Il parametro move-constructor è un riferimento di rvalore) – sellibitze

risposta

7

La regola è la seguente

  • Se il compilatore può fare RVO, allora è permesso di farlo, e nessuna copia e nessuna mossa è fatta.
  • In caso contrario, viene utilizzato il costruttore appropriato.

come dici tu, la temporanea è un rvalue, e quindi si seleziona il costruttore movimento, a causa di una regola in 13.3.3.2/3, che dice che un riferimento rvalue si lega a un rvalue meglio di un riferimento lvalue. Nel decidere se utilizzare lo spostamento o il costruttore di copie, la risoluzione di sovraccarico sarà quindi preferibile al costruttore di movimento.

La regola che il compilatore può eseguire RVO è scritta a 12.8/15.

2

Tutti i valori restituiti sono considerati rvalues, pertanto se il compilatore non implementa RVO in questo caso, deve utilizzare il costruttore di movimento anziché il costruttore di copie.

+1

Non so come interpretare "deve usare la mossa". AFAIU, supposto un compilatore con supporto U/NRVO, il flusso decisionale è il seguente: 1) se RVO-friendly, ottimizzare qualsiasi operazione di spostamento/copia, 2) altrimenti se è disponibile il costrutto di movimento, utilizzarlo 3) altro se copia costruttore disponibile, usalo 4) altro programma mal formato – mloskot

+0

@mloskot Voglio dire che il costruttore di movimento è selezionato poiché è più adatto per il sovraccarico rispetto al costruttore di copie. – Motti

+2

Capito. L'ipotesi implicita che il censore esistesse non era chiara per me. Come mittente è selezionato, ma solo se esiste. – mloskot

Problemi correlati