Non c'è alcuna differenza tra questi due metodi, e dovresti usare quello che meglio comunica il suo intento per te.
Paragrafo 12,8/31 sulla copia elisione specifica:
Quando determinati criteri sono soddisfatti, un'implementazione è consentito di omettere la copia costruzione/spostamento di un oggetto classe , anche se il costruttore preselezionata l'operazione di copia/spostamento e/o il distruttore per l'oggetto hanno effetti collaterali. In tali casi, l'implementazione considera l'origine e la destinazione dell'operazione omessa copia/spostamento come due modi diversi di riferirsi allo stesso oggetto, e la distruzione di quell'oggetto si verifica in un secondo momento in cui i due oggetti sono stati distrutti senza l'ottimizzazione. Questa elisione delle operazioni di copia/spostamento, chiamato copia elisione, è consentito nei seguenti casi (che possono essere combinati per eliminare le copie multiple):
- in una dichiarazione return
in una funzione con un tipo di classe di ritorno , 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 funzione, l'operazione di copia/spostamento può essere omessa costruendo l'oggetto automatico direttamente nel valore di ritorno della funzione
- [...]
Come si può vedere, sia la creazione di una temporanea e una id-espressione denominazione di un oggetto locale con durata memorizzazione automatica qualificano per la copia elision.
Inoltre, il compilatore tratterà locale temp
come un rvalue (leggi: come una temporanea, in questo caso) ai fini di ritorno da una funzione. Paragrafo 12.8/32 del C++ 11 specifica standard:
Quando i criteri per l'elisione di un'operazione di copia sono stati raggiunti o sarebbero soddisfatti, salvo per il fatto che l'oggetto di origine è un parametro di funzione, e la l'oggetto da copiare è designato da un lvalue, la risoluzione di sovraccarico a selezionare il costruttore per la copia viene prima eseguita come se l'oggetto sono stati designati da un valore massimo. [...]
A causa di questo, vi consiglierei vivamente rimozione la qualificazione const
dal tipo di ritorno:
const X operator + (const X& left, const X&right)
// ^^^^^
// Don't use this!
In C++ 11, questo inibisce la semantica muoversi, perché non si può passare da un oggetto const
, anche se è un valore rvalue - in breve, il costruttore di spostamenti di X
, a condizione che ne esiste uno, non verrà selezionato e verrà chiamato il costruttore di copia.
In C++ 11, 'ritorno {left.i + right.I}' è il metodo # 3 che ... fa anche la stessa cosa (dopo ottimizzazioni banali). – Yakk