2017-05-08 4 views
2

Je possède ce structLe constructeur Rvalue n'est pas appelé?

struct A { 
    A()    { cout << "Default\n"; } 
    A(const A& a) { cout << "Const lvalue\n"; } 
    A(const A&& a) { cout << "Const rvalue\n"; } 
    A(A& a)   { cout << "Lvalue\n"; } 
    A(A&& a)  { cout << "Rvalue\n"; } 
}; 

que j'utilise pour comprendre rvalues ​​/ lvalues.

Quand vous faites

A a1; 
A a2{ a1 }; 

const A a3; 
A a4{ a3 }; 

Il produit correctement

> Default 
> lvalue 
> Default 
> Const lvalue 

Le problème est que quand je fais quelque chose comme

A a{ A() }; 

La sortie est par défaut. Mais n'est-ce pas A() un rvalue là? Ne faut-il pas appeler A::A(A&&) ou A::A(const A&&)? Que se passe-t-il ici?

+3

Qu'il me soit permis de vous diriger vers [ 'std :: move'] (http://en.cppreference.com/ w/cpp/utilitaire/move) – InternetAussie

+0

Merci, cela a résolu le problème, mais pourquoi dans l'exemple je n'ai donné aucun constructeur a été appelé? – Garmekain

+0

Le constructeur de copie n'est pas certain d'être appelé. Dans ce cas, le compilateur a probablement créé 'A()' directement à la place de 'a' sans copier. – zoska

Répondre

4

Vous ne voyez pas Rvalue imprimé car le compilateur est eliding le déplacement. Ceci est autorisé même si le constructeur a des effets secondaires.

Si vous passez -fno-elide-constructors à GCC ou Clang alors vous verrez la sortie:

clang++ -std=c++14 -O2 -pedantic -fno-elide-constructors main.cpp && ./a.out 
Default 
Rvalue 

clang++ -std=c++14 -O2 -pedantic main.cpp && ./a.out 
Default