Pourquoi pas un destructeur être marqué constexpr?

En C++, vous pouvez déclarer beaucoup de choses comme constexpr: variables, fonctions (y compris les fonctions des membres et les opérateurs), constructeurs, et depuis C++1z, aussi if instructions et les expressions lambda. Toutefois, la déclaration d'une destructeurconstexpr génère une erreur:

struct X {
    constexpr ~X() = default; // error: a destructor cannot be 'constexpr'
};

mes questions:

  1. Pourquoi pas un destructeur être marqué constexpr?
  2. Si je n'ai pas fournir une destructeur, est le générées implicitement destructeur constexpr?
  3. Si je déclare un destructeur par défaut (~X() = default;), est-il automatiquement constexpr?
26
demandé sur muru 2017-07-13 08:12:03

5 réponses

selon le projet de base.types de#10 peut-être un type de classe qualifié cv qui possède toutes les propriétés suivantes:

un type de classe possiblement qualifié cv qui possède toutes les propriétés suivantes:

(10.5.1) - il a un destructeur trivial,

(10.5.2) - il s'agit soit d'un type de fermeture, soit d'un type d'agrégat, soit d'une au moins un modèle de constructeur ou de constructeur (éventuellement héritée d'une classe de base), qui n'est pas une copie ou un constructeur de déplacement,

(10.5.3) - s'il s'agit d'une union, au moins une de ses données non statiques les membres sont de type littéral non volatil

(10.5.4) - s'il n'est pas un syndicat, tous ses membres de données non statiques et ses classes de base sont: types littéraux non volatils.

Question 1: Pourquoi un destructeur ne peut-il pas être marqué comme constexpr?

parce que seuls les destructeurs triviaux sont qualifiés pour les constexpr Est le suivant la section pertinente de l' projet

Un destructeur est trivial si il n'est pas fourni par l'utilisateur et si:

(5.4) - le destructeur n'est pas virtuel,

(5.5) - toutes les classes de base directes de sa classe ont trivial les destructeurs, et

(5.6) - pour tous les non-membres de données statiques de sa classe qui sont de type de classe (ou un tableau), chaque classe a un trivial destructeur.

Sinon, le destructeur est non-trivial.

Question 2: Si Je ne fournis pas de destructeur, le destructeur implicitement généré constexpr?

Oui, parce qu'implicitement généré le destructeur est trivial, donc il est qualifié pour constexpr

Question 3: Si je déclare un destructeur par défaut (~X () = par défaut;), est-ce automatiquement constexpr?

en effet, ce destructeur est déclaré par l'utilisateur et implicitement-généré et donc il est qualifié pour constexpr.


Je n'arrive pas à trouver de référence directe qui ne soit que triviale destructors sont qualifiés pour constexpr mais si le destructeur n'est pas trivial, c'est pour assurer ce type de classe n'est pas cv-qualified. Donc implicite que vous ne pouvez pas définir un destructorcv-qualified classe.

10
répondu Hemant Gangwar 2017-07-13 07:38:21

si ce que vous cherchez est de raisonner derrière la restriction, jetez un oeil à ce document ce qui indique clairement que la restriction est artificielle - il n'y a pas de propriété intrinsèque des destructeurs qui les empêchent de fonctionner dans des contextes de constexpr, et en effet les développeurs de compilateurs conviennent que les supporter dans des contextes de constexpr sera trivial pour implémenter.

je suppose que le C++ comité des normes placés à l'origine de la restriction en C++11, parce qu'ils ne veulent pas traiter avec les destructeurs à l'époque et il était plus facile de gouverner entièrement.

4
répondu saarraz1 2018-03-03 00:39:52

pourquoi un destructeur ne peut-il pas être marqué constexpr?

la norme C++11 est spécifique à l'utilisation de constexpr pour les constructeurs et la fonction de membre non statique. Il ne dit rien de particulier sur destructeur. On peut supposer que les destructeurs doivent être traités comme des fonctions non statiques.

constexpr peut être utilisé que pour const fonctions des membres. Depuis un destructeur ne peut pas être const fonction membre, il ne peut pas être qualifié comme un constexpr fonction membre.

Si je ne fournis pas un destructeur, est implicitement généré destructeur constexpr.

Depuis

constexpr ~X() = default;

est une erreur, il me semble logique que le compilateur a généré destructeur n'est pas un constexpr fonction. Je ne trouve rien dans le standard pour justifier ma déclaration. Je suis dans le doute.

Si je déclare un destructeur par défaut (~X() = default;), est-il automatiquement constexpr

je ne pense pas. Encore une fois, je ne trouve rien dans la norme qui justifie ma déclaration. Je suis dans le doute.


FWIW, g++ compile et s'appuie le programme suivant l'amende juste.

struct X {
   constexpr X(int i) : i_(i) {}
   ~X() = default;
   int i_;
};

int main()
{
   const X x(10);
}
3
répondu R Sahu 2017-07-13 05:59:33

Référence dis:

constexpr destructeurs

dans la plupart des cas, afin de créer un objet D'un type T dans une constante expression, la destruction de T doit être triviale. Cependant, non-trivial les destructeurs sont une composante importante du C++ moderne, en partie l'usage répandu de L'idiome RAII, qui est également applicable dans évaluations constexpr. Les destructeurs Non triviaux pourraient être pris en charge constant expressions, comme suit:

  • permettre aux destructeurs d'être marqués comme constexpr
  • Faire défaut destructeurs constexpr si seulement ils invoquer constexpr destructeurs
  • pour les variables constexpr, exiger que l'évaluation du destructeur est une expression constante (sauf que l'objet détruit peut être modifié dans son propre destructeur

cependant, aucun cas d'utilisation irréfutable n'est connu pour une telle caractéristique, et il n'y aurait être un coût de mise en œuvre non négligeable s'assurer que: les destructeurs fonctionnent au bon moment.

2
répondu rsp 2017-07-13 05:38:15

Un destructeur ne peut pas être constexpr parce que constexpr les fonctions ne peuvent pas avoir d'effets secondaires et les destructeurs, par définition, ne sont utiles que par les effets secondaires. En bref, il serait inutile d'avoir un destructeur est constexpr.

Un objet ne peut pas être constexpr si son destructeur est non-trivial. Un défaut, si trivial, sera considéré constexpr

Live

[la classe.dtor]

Chaque le spécificateur decl du spécificateur decl-seq d'une déclaration de destructeur (le cas échéant) doit être friend,inline, ou virtual.

Manquant, constexpr. Vous pouvez donc le prendre comme: parce que la norme dit TM

2
répondu Passer By 2017-07-13 09:49:26