2014-07-24 18 views
6

Qualcuno mi ha suggerito che a un ottimizzatore è consentito scambiare liberamente il parametro pass-by-const-reference e con parametro-passing-by-value in qualsiasi funzione che non modificare il parametro. È consentito dallo standard C++?È garantita una chiamata al costruttore di copie quando si passa argomento per valore

o indicazioni diverse, il codice

struct MyClass { 
    MyClass(MyClass const& mc) { std::cout << "xxx" << std::endl; } 
}; 

void foo(MyClass mc) { } 

MyClass mc; 
foo(mc); 

non garanzia standard di C++ che "xxx" viene sempre stampato? (Riferimento allo standard apprezzato)

+0

Il compilatore può generare qualsiasi codice desiderato che si comporta come richiede il codice. Non può magicamente omettere qualcosa come stampare il tuo messaggio, a meno che non ci sia un esplicito permesso per questo (e ciò accade solo in un caso, che è la copia elisione, e che non si applica alla tua situazione). –

+0

A meno che non sia il tipo di dati di base o la tua funzione probabilmente modificherà il valore all'interno, passerei sempre da const ref come "default". Questa è solo la mia opinione personale. –

risposta

8

Sì, il costruttore di copie verrà utilizzato qui. Copia elisione è consentito solo in determinate circostanze, specificato dal C++ 11 12.8/31:

  • in un comunicato return ...
  • in un rimessa espressione ...
  • quando un oggetto classe temporanea ... sarebbe stato copiato/spostato ...
  • quando il eccezione dichiarazione di un gestore di eccezioni dichiara un oggetto dello stesso tipo ... come l'oggetto eccezione

Nessuno di questi si applicano qui, anche se il terzo si applicherebbe se hai superato un valore temporaneo:

foo(MyClass()); 

In questo caso il messaggio potrebbe non essere stampata.

Inoltre, se il copy-constructor non ha avuto effetti collaterali, la copia potrebbe essere elidata in ogni caso sotto la regola "as-if" (indipendentemente dal fatto che l'argomento fosse o meno temporaneo), poiché così facendo non avrebbe effetto il comportamento visibile del programma.

+0

Intendi ciò in 'foo (MyClass());' il compilatore non deve stampare il messaggio? Quindi la clausola if nella tua ultima frase sarebbe fuorviante. Almeno, è così che capisco il punto 3. –

+0

@ TobiasBrüll: Sì, se l'argomento è temporaneo, quindi si applica il punto 3, quindi il messaggio potrebbe non essere stampato. L'ultima frase si applicherebbe in ogni caso, se non ci fossero effetti collaterali (ma non se ci sono, come nel tuo esempio); scusa se l'hai trovato fuorviante, cercherò di trovare un modo migliore di esprimerlo. –

Problemi correlati