Copie constructeur n'est pas appelé pour la copie ou l'initialisation optimisé?
-
08-10-2019 - |
Question
Si le constructeur de copie est faite private
puis dans
Cas 1:. Pas d'erreur, le compilateur ne se soucie pas si le constructeur de copie a été défini dans la classe
Cas n ° 2:. Erreur, constructeur de copie est privée et quand il est fait public
, il est éludée
optimise-t-il directement la copie sans remarquer que si le constructeur a fait private
?
#include <string>
using std::string;
class T
{
string s;
T(const T &obj):s(obj.s){}
public:
T(const string &str):s(str){}
};
int main()
{
T a = ("Copy Initialization"); //Case: 1
T b = T("Copy Initialization"); //Case: 2
}
La solution
Cas n ° 2 est de 12,8 / 31 N3225:
Le programme A est mal formé si la copier / constructeur de déplacement ou la copie / déplacement opérateur d'affectation d'un objet est implicitement ODR-utilisé et la spéciale fonction membre n'est pas accessible.
Tout simplement parce que la copie cteur est éludée ne signifie pas qu'il est pas ODR-utilisé. 3,2 / 2:
Un membre d'un ensemble de candidat fonctions est ODR-utilisée si elle est sélectionnée par la résolution de surcharge lorsque appelé d'un expression potentiellement évalués. [Note: ce programme couvre les appels vers le nom fonctions (5.2.2), ateur OPER- surcharge (article 13), l'utilisateur dé fi nies conversions (12.3.2), l'allocation fonction pour le placement nouveau (5.3.4), comme ainsi que l'initialisation de non-défaut (8,5). Un constructeur de copie ou de déplacement constructeur est ODR utilisé même si la appel est en fait éludée par le la mise en oeuvre. -end ndlr]
Méfiez-vous bien sûr que MSVC est pas entièrement C ++ 0x conforme, parce que (a) C ++ 0x est pas une norme encore, et n'a pas été finalisé; et (b) MSVC n'a pas tout mis en œuvre à jour de toute façon. Mais ce genre de choses ne sont pas substantiellement changé de C ++ 03, donc je suis assez confiant l'explication tient toujours.
Cas n ° 1 serait sous cela aussi, sauf que les deux C ++ 03 compilateurs J'ai vérifié qu'il ne soit pas loin parce qu'il n'y a pas de conversion possible à partir d'une chaîne littérale à T. Je ne peux pas être dérangé pour vérifier s'il y a des séquences de conversion supplémentaires autorisés en C ++ 0x, il pourrait y avoir une nouvelle clause partout: -)
Il est encore un mystère pour moi pourquoi MSVC permet le cas 1 jamais, même avec une copie publique cteur. Est-ce qu'il permet en stricte mode C ++ 03?
Autres conseils
Cas n ° 1:. Pas d'erreur , le compilateur ne se soucie pas si le constructeur de copie a été défini dans la classe
T a = ("Copy Initialization"); href="http://ideone.com/DbYAx" rel="nofollow"> devrait donner une d'erreur, car il n'y a pas de constructeur approprié pour convertir de "const char [20]"
à "T"
Avez-vous T a = std::string("Copy Initialization");
moyen?
optimise-t-il directement la copie sans remarquer que si le constructeur a été privatisé?
Non, il ne peut pas. Compilateurs effectuent généralement une analyse syntaxique et sémantique avant la phase d'optimisation de code.