web-dev-qa-db-fra.com

Pourquoi les déclarations de décomposition ne peuvent-elles pas être constexpr?

Considérez l'extrait suivant pour tester les prochaines déclarations de décomposition des fonctionnalités C++ 17 (anciennement appelées liaisons structurées)

#include <cassert>
#include <utility>

constexpr auto divmod(int n, int d)
{
    return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d}
}

int main()
{
    constexpr auto [q, r] = divmod(10, 3);
    static_assert(q == 3 && r ==1);
}

Cela échoue sur g ++ 7-SVN et clang-4.0-SVN avec le message:

la déclaration de décomposition ne peut pas être déclarée 'constexpr'

Supprimer la définition constexpr et passer à une fonction assert() régulière fonctionne sur les deux compilateurs.

Aucun des articles du WG21 sur cette fonctionnalité ne mentionne le mot clé constexpr, ni dans le positif ni dans le négatif.

Question: pourquoi les déclarations de décomposition ne peuvent-elles pas être constexpr? (à part "parce que le Standard le dit").

39
TemplateRex

Question: pourquoi les déclarations de décomposition ne peuvent-elles pas être constexpr? (à part "parce que le Standard le dit").

Il n'y a pas d'autre raison. La norme dit dans [dcl.dcl] p8:

Le decl-specifier-seq ne doit contenir que le type-specifierauto (7.1.7.4) et cv-qualifiers .

Cela signifie qu'il ne peut pas être déclaré avec constexpr.

Cela a fait l'objet d'un commentaire de l'organisme national sur le CD C++ 17, voir US-95 dans P0488R :

Commentaire : Il n'y a aucune raison évidente pour laquelle les déclarations de décomposition ne peuvent pas être déclarées comme statiques, thread_local ou constexpr.
Changement proposé: Autoriser constexpr, static et thread_local à l'ensemble autorisé de décl-spécificateurs .

Les commentaires GB 16 et GB 17 sont également liés.

Ces commentaires ont été rejetés pour C++ 17 après examen par le groupe de travail sur l'évolution à la réunion de novembre 2016. On ne savait pas exactement ce que certaines classes de stockage signifieraient sur une déclaration de liaison structurée, et exactement comment changer la spécification pour autoriser constexpr (simplement l'autoriser dans la grammaire ne dirait pas ce que cela signifie). Un document explorant l'espace de conception a été demandé. Il devrait être possible de changer cela à l'avenir sans casser aucun code, mais il n'y avait pas de temps pour le faire pour C++ 17.

38
Jonathan Wakely