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?

26
demandé sur Me myself and I 2013-12-28 06:26:22

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 constructeur constexpr (7.1.5), le constructeur par défaut implicitement défini est constexpr. [..]

[C++11: 7.1.5/3]: La définition d'une fonction constexpr 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ée constexpr seulement si elle aurait été implicitement déclarée comme constexpr, 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.

26
répondu Lightness Races in Orbit 2013-12-28 02:47:00