2014-09-11 9 views

risposta

14

Nel tuo caso, returnedStr saranno spostarsi-costruito dal valore di ritorno di GetString(), ma questo valore di ritorno sarà copiare-costruiti da str(1). Se str non fosse const, il valore di ritorno sarebbe stato spostato da esso.

noti che in entrambi i casi, l'ottimizzazione valore di ritorno è ancora applicabile, quindi il compilatore può ancora costruire il valore di ritorno (o anche str stesso) direttamente nello spazio di returnedStr, saltando uno o entrambi costruzioni copia/spostamento. Ciò è garantita da C++ 11 12.8/31:

Quando determinati criteri sono soddisfatti, un'implementazione è consentito omettere la copia costruzione/spostamento di un oggetto classe , anche se il costruttore di copia/spostamento e/o distruttore per l'oggetto hanno effetti collaterali. In tali casi, l'implementazione considera l'origine e la destinazione dell'operazione di copia/spostamento omessa semplicemente come due diversi modi di riferirsi allo stesso oggetto, e la distruzione di tale oggetto si verifica in un momento successivo a quando i due oggetti sarebbe stato distrutto senza l'ottimizzazione. Questa elisione copia/spostare operazioni, chiamato copia elisione, è consentito nei seguenti casi (che possono essere combinati per eliminare le copie multiple):

  • in una dichiarazione return in una funzione con una classe restituisce tipo, quando l'espressione è il nome di un oggetto automatico non volatile (diverso da una funzione o un parametro catch-clause) con lo stesso tipo cv-non qualificato come tipo di ritorno della funzione, l'operazione di copia/spostamento può essere omessa costruendo l'oggetto automatico direttamente nel valore di ritorno della funzione

  • ...

  • quando un oggetto classe temporanea che non è stato legato ad un riferimento (12.2) viene copiato/spostato a un oggetto di classe con lo stesso tipo cv-qualificato, la copia/operazione di spostamento può essere omesso dal costruire l'oggetto temporaneo direttamente nella destinazione della copia omessa/spostare

il primo punto riguarda l'elisione della costruzione valore di ritorno, l'altro copre spostando il ritorno valore in returnedStr. Si noti il ​​requisito relativo allo "stesso tipo cv-non qualificato", il che significa che questo funziona indipendentemente dai qualificatori di cv.


(1) Si noti che se stessimo parlando di una classe X diverso std::string, uno che ha fornito un costruttore mossa prendendo un const X&&, allora davvero il valore di ritorno sarebbe mossa costruito utilizzando questo costruttore (qualunque semantica potrebbe avere).

+0

@PiotrS. Aggiunto, anche se non penso che la risposta ne abbia davvero bisogno. E 'solo una normale copia elision al lavoro. – Angew

+0

bello, ma non intendevo i requisiti per ellision, piuttosto il ritorno regolare –

+0

anche, 'X (const X &&);' è un costruttore di movimento * valido * che verrà invocato per l'esempio precedente se è dichiarato, anche se non è ragionevole –

6

La risposta di Angew è giusta ma chi può ricordare tutte le regole dell'avvocato linguistico?

Per aiutarmi a ricordare più facilmente ho scritto le seguenti regole che provenivano dalla bocca di STL.

15) non restituiscono locali come const [16]

$ Inibisce spostare semantica

16) Non utilizzare mossa quando il ritorno locale per valore di esattamente lo stesso tipo [16]

$ NVRO non verrà utilizzato se si esegue questa operazione.

17) non tornano da rvalue di riferimento (& &) [16]

$ A meno che davvero sai cosa stai facendo.

Note:

[16] non aiutano il compilatore, Going Native 2013 http://www.youtube.com/watch?v=AKtHxKJRwp4

+0

Grazie, ecco come mi piacciono le mie risposte :) –

Problemi correlati