Le constructeur de copie explicite est ignoré même si l’argument exact est fourni

Le constructeur de copie a été fourni. Lors de son utilisation, exactement le même type est passé à argument. Il semble que le compilateur (gcc / g ++ 4.8.2) ignore l’existence du constructeur de copie explicite. Le code génère une erreur de compilation. Pourquoi? L’erreur est:

t.cpp: In function 'A f(const A&)': t.cpp:19:12: error: no matching function for call to 'A::A(const A&)' return a; //compilation error with gcc 4.8.2 ^ t.cpp:19:12: note: candidate is: t.cpp:14:5: note: A::A() A(){} ^ t.cpp:14:5: note: candidate expects 0 arguments, 1 provided t.cpp:21:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ 

J’ai déjà traversé
Pourquoi je ne peux pas invoquer ‘explicit a (ssortingng x)’? et constructeur de copie explicite . Sur la base de ces liens et j’ai essayé la construction de copie forcée (pour éviter l’optimisation, reportez-vous à mon code commenté).

 #include  using namespace std; class A { public: explicit A(const A& a) // an explicit copy constructor //A(const A&) // an copy constructor, pretty much default one. //using it solves any comstack problem. { cout << "\nin the copy constructor" << endl; } A(){} }; ////////////////////////////////// A f(const A &a) { return a; //compilation error with gcc 4.8.2 //return A(a); // even tried this to avoid optimization. does not work } /////////////////////////////////// int main() { //A a; //f(a); return 0; } 

Le constructeur de copie est appelé implicitement au retour (et également lors du passage d’un argument par valeur).

Ce code appelle le constructeur de copie deux fois:

 A f(const A &a) { return A(a); } 

Le A(a) signifie une copie explicite , puis il y a une copie implicite au retour.

Si vous souhaitez interdire la copie implicite, vous ne pouvez pas non plus retourner par copie. Vous devrez retourner par référence ou par pointeur (probablement avec une new copie).


En C ++ 11 et supérieur, je pense que le code ci-dessus appelle plutôt le constructeur de déplacement ( si défini) pour le retour (bien qu’il appelle toujours le constructeur de copie pour l’appel explicite), ce qui devrait être plus efficace.