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:
- Pourquoi pas un destructeur être marqué
constexpr
? - Si je n'ai pas fournir une destructeur, est le générées implicitement destructeur
constexpr
? - Si je déclare un destructeur par défaut (
~X() = default;
), est-il automatiquementconstexpr
?
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 destructor
cv-qualified
classe.
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.
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 automatiquementconstexpr
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);
}
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.
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
Chaque le spécificateur decl du spécificateur decl-seq d'une déclaration de destructeur (le cas échéant) doit être
friend
,inline
, ouvirtual
.
Manquant, constexpr
. Vous pouvez donc le prendre comme: parce que la norme dit TM