gcc, clang e VS2015 non mi Elide la chiamata al costruttore mossa nel seguente codice, dopo aver lanciato oggetto a
. Mi sembra che le condizioni stabilite nel punto (31.2) del §8.12 [class.copy]/31 (N4140) siano soddisfatte.C'è qualche motivo speciale per cui il costruttore di movimento non viene elidato nello snippet mostrato di seguito?
#include <iostream>
struct A
{
A() { std::cout << "Default ctor " << '\n'; }
A(const A& a) { std::cout << "Copy ctor" << '\n'; }
A(A&& a) { std::cout << "Move ctor" << '\n'; }
~A() { std::cout << "Destructor " << '\n'; }
};
int main()
{
try
{
A a;
throw a;
}
catch(A& a) { std::cout << "Caught" << '\n'; }
}
noti che a
è un lvalue, ma secondo §12.8/32, risoluzione di sovraccarico per selezionare il costruttore per la copia viene eseguita prima come se l'oggetto fosse designato dalla rvalue. Cioè, la chiamata al costruttore di movimento è OK. Se si cancella la definizione del costruttore di mosse sopra, viene invocato il costruttore di copia, ma, di nuovo, non viene eliminato!
Capisco che la copia-elisione non è richiesta dallo Standard, ma sono curioso di sapere se c'è qualche condizione speciale che potrebbe giustificare il fatto, che i tre compilatori sopra menzionati evitino questa ottimizzazione, in questo particolare esempio .
Un'uscita esempio per gcc, dal link sopra:
g ++ -std = C++ 14 -O2 -Wall -pedantic -pthread main.cpp & & ./a.out
default ctor
Spostare ctor
Destructor
Ca effettuato l 'acquisto
Destructor
è lungo il percorso d'eccezione, chi se ne frega? l'equivalente [percorso felice] (http://coliru.stacked-crooked.com/a/44bf1d21b3e185ba) ottimizza completamente – TemplateRex
penserei si tratta di una formulazione che una variabile locale non può essere eliso se la sua costruzione ha effetti collaterali. Non sono sicuro che ci sia davvero un conflitto ma come regole semplici potrebbero essere effettivamente in conflitto per il compilatore. –
@ Cheersandhth.-Alf: Copia-elisione è esplicitamente consentita in modo che il compilatore possa farlo anche se ci sono effetti collaterali. –