2017-01-26 3 views
2

J'ai un struct qui stocke un entier:Comprendre que le constructeur est appelé

struct foo { 
    int value; 

    foo(int value) : value(value) { 
     std::cout << "value constr\n"; 
    } 

    foo(foo const&) { 
     std::cout << "copy constr\n"; 
    } 

    foo(foo&&) { 
     std::cout << "move constr\n"; 
    } 
}; 

Dans la principale méthode que je fais ce qui suit:

foo bar = foo(foo(foo(42))); 

À ce moment-là, je pense le constructeur habitude d'être appelé d'abord, puis déplacer le constructeur plusieurs fois parce que l'argument sera un rvalue. Cependant, la sortie est seulement "value constr".

Pourquoi ni les moteurs de copie ni de déplacement ne sont appelés et que se passe-t-il réellement dans cet exemple?

Répondre

3

En raison de Copy elision, le constructeur approprié sera appelé pour construire l'objet directement, copier/déplacer les constructeurs seront omis. Et puisque C++ 17 ce comportement est garanti.

Dans les cas suivants, les compilateurs sont tenus d'omettre les constructeurs et contre la copie d'objets de classe mouvements, même si copier/déplacer constructeur et l'destructor ont des effets secondaires observables:

  • Lors de l'initialisation, si l'expression de l'initialiseur est prvalue et que la version cv -qualifiée du type source est la même classe que la classe de la destination, l'expression de l'initialiseur est utilisée pour initialiser l'objet de destination:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x