Est-il possible de déclarer constexpr classe dans un en-tête et de le définir dans un document distinct .fichier cpp?
J'ai une classe Dimension
lequel j'ai défini (comme toutes mes classes) dans un fichier Dimension.h:
class Dimension
{
public:
constexpr Dimension() noexcept;
constexpr Dimension(int w, int h) noexcept;
int width;
int height;
};
Je pensais que je pouvais, comme dans toutes mes classes, mettre la définition dans un autre Dimension.cpp:
#include "Dimension.h"
constexpr Dimension::Dimension() noexcept : width(0), height(0) {}
constexpr Dimension::Dimension(int w, int h) noexcept : width(w), height(h) {}
Mais lorsque j'essaie d'utiliser la classe, le compilateur me dit:
avertissement: la fonction inline ' constexpr Dimension::Dimension()
" utilisé mais jamais défini
et, tout en les reliant:
undefined reference to 'pong::graphics::Dimension::Dimension()
'
(même avec l'autre constructeur)
Si je définir la classe dans l'en-tête comme suit:
class Dimension
{
public:
constexpr Dimension() noexcept : width(0), height(0) {}
constexpr Dimension(int w, int h) noexcept : width(w), height(h) {}
int width;
int height;
};
et omettre le .fichier cpp, tout fonctionne bien.
Je suis en utilisant GCC 4.9.2. Pourquoi définition distincte de ne pas travailler?
- Le point de l'ensemble d'un
constexpr
fonction est de permettre l'évaluation de la fonction au moment de la compilation. Qui serait assez difficile à enlever si le compilateur ne peut pas voir le corps de ladite fonction. - "Pourquoi ne séparée définition, pas de travail?" - Parce que la langue ne le permet pas. L'accepter, de le faire correctement, passer.
- Je soupçonnais déjà, mais je ne suis pas sûr si je peux l'expliquer (avec des références peut-être) pourquoi il se passe exactement. Je n'ai rien trouvé au sujet de cette tout en googler, j'ai donc pensé à une nouvelle question pour ce qui était approprié.
- @TimoTürschmann "mais je ne suis pas sûr si je peux l'expliquer (avec des références peut-être) pourquoi il arrive ..." À reformuler @IgorTandetnik s 'commentaire un peu: Le compilateur a besoin de voir un
constexpr
hcompletely étendu à chaque fois qu'il est utilisé pour insérer l'expression correcte en place. Étape de lien est trop tard. - Si vous insistez sur le chapitre et le verset: 7.1.5/2
constexpr
fonctions etconstexpr
constructeurs sont implicitement en ligne. 3.2/4 Une fonction inline, doivent être définis dans chaque unité de traduction dans lequel il est odr-utilisé.
Vous devez vous connecter pour publier un commentaire.
Si un
constexpr
fonction n'est pas définie dans l'en-tête, le compilateur ne peut pas voir la définition de laconstexpr
fonctions lors de la compilation de tous les autres fichiers source.Évidemment, si il ne peut pas voir la définition des fonctions, il ne peut pas effectuer les étapes nécessaires pour les calculer au moment de la compilation. Ainsi, toutes les
constexpr
les fonctions doivent être définies partout où ils sont utilisés.Merci @IgorTandetnik:
[dcl.constexpr] §7.1.5/2
[de base.def.odr] §3.2/4
Ce que vous demandez ne peut être réalisé avec une limitation importante: la constexpr fonction peut être appelée à partir de l'intérieur de l'unité de traduction (c'est à dire le fichier source) où il est défini. Ce n'est pas appropriée pour l'exemple que vous avez donné, puisque le constructeur est destiné à faire partie de la classe' interface publique. Toutefois, il peut être très utile dans d'autres cas, par exemple, de définir les méthodes privées comme constexpr et ensuite utiliser leurs valeurs de retour dans les expressions qui doivent être connus au moment de la compilation, par exemple, le modèle d'instanciations, instruction de commutation d'étiquettes, etc.