Nel codice seguente un oggetto s
della classe S
viene utilizzato per inizializzare un oggetto della classe D
con un'inizializzazione diretta D d(s);
. La funzione di conversione S :: operator D() viene utilizzata per convertire l'oggetto s
in un oggetto temporaneo di tipo D
. Quindi, gcc e clang elidano entrambi la chiamata esplicita al costruttore di spostamenti D(&&)
, per spostare questo oggetto temporaneo in d
. Vedi live example.gcc e clang entrambi elidano la chiamata al costruttore di movimento nello snippet seguente. È corretto?
#include <iostream>
struct D;
struct S{ operator D(); };
struct D{
D(){}
D(D&&) { std::cout << "move constructor" << '\n'; }
};
S::operator D() { std::cout << "conversion function" << '\n'; return D(); }
int main()
{
S s;
D d(s);
}
sto contestando la correttezza di questa elisione, per i seguenti motivi:
- Questo caso è trattato nel primo punto sub-proiettile in §8.5/16 (N3337), che è silenzioso di elisione.
Se l'inizializzazione inizializzazione diretta, o se non é copia-inizializzazione dove la versione cv-non qualificato del tipo di origine è la stessa classe, o una classe derivata, la classe della destinazione i costruttori sono considerati. I costruttori applicabili vengono enumerati (13.3.1.3) e il migliore viene scelto tramite la risoluzione di sovraccarico (13.3). Il costruttore così selezionato viene chiamato per inizializzare l'oggetto , con l'espressione di inizializzazione o elenco di espressioni come argomento (i) . Se non viene applicato alcun costruttore o se la risoluzione di sovraccarico è ambigua, l'inizializzazione non è corretta.
- Si noti che il punto successivo di puntata indica esplicitamente la possibilità di elisione.
- La chiamata al costruttore di spostamento è esplicita. Come può essere eliso?