Dois-je marquer un constructeur généré par le compilateur comme constexpr?
Y a-t-il une différence entre faire:
X() = default;
Et
constexpr X() = default;
Default-la construction de la classe dans des expressions constantes fonctionne bien, y a-t-il donc une différence entre ces deux exemples? Dois-je utiliser l'un plutôt que l'autre?
1 réponses
Puisque le constructeur implicite est en fait constexpr
dans votre cas ...
[C++11: 12.1/6]:
[..] si ce constructeur par défaut écrit par l'utilisateur répond aux exigences d'un constructeurconstexpr
(7.1.5), le constructeur par défaut implicitement défini estconstexpr
. [..]
[C++11: 7.1.5/3]:
La définition d'une fonctionconstexpr
doit satisfaire aux contraintes suivantes:
- , il ne doit pas être virtuel (10.3);
- son type de retour doit être un littéral type;
- chacun de ses types de paramètres doit être un type littéral;
- sa fonction-corps doit être
= delete
,= default
, ou un composé déclaration qui contient uniquement
- instructions null,
- static_assert-déclarations
typedef
déclarations et alias-déclarations {[20] } qui ne définissent pas les classes ou les énumérations,- à l'aide de déclarations,
- en utilisant-directives ,
- et exactement une déclaration de retour;
- chaque appel de constructeur et conversion implicite utilisé pour initialiser la valeur de retour (6.6.3, 8.5) doit être l'un de ceux autorisés dans une expression constante (5.19).
... les déclarations sont en fait équivalentes:
[C++11: 8.4.2/2]:
une fonction explicitement par défaut peut être déclaréeconstexpr
seulement si elle aurait été implicitement déclarée commeconstexpr
, et peut explicite spécification d'exception seulement si il est compatible (15.4) avec le spécification d'exception sur la déclaration implicite. si une fonction est explicitement par défaut lors de sa première déclaration,
- , il est implicitement considéré comme
constexpr
si la déclaration implicite serait,- Il est implicitement considéré comme ayant la même exception-Spécification {[20] } que s'il avait été implicitement déclaré (15.4), et
- dans le cas d'un constructeur de copie, constructeur de déplacement, de copie opérateur d'affectation, ou de déplacer l'opérateur d'affectation, il doit avoir le même type de paramètre que si elle avait été déclarée implicitement.
Alors faites l'un ou l'autre - ça n'a pas d'importance.
Dans le cas général, si vous voulez vraiment qu'un constructeur soit constexpr
, cependant, il peut être sage de laisser le mot-clé pour que vous obteniez au moins une erreur de compilateur s'il ne répond pas aux critères; en le laissant de côté, vous pouvez obtenez un constructeur non - constexpr
sans le réaliser.