web-dev-qa-db-fra.com

Différence entre constexpr et variable globale constexpr statique

Dans la norme C++ 11, quelle est la différence entre constexpr et static constexpr variables globales lorsqu'elles sont définies dans un en-tête? Plus précisément, lorsque plusieurs unités de traduction incluent le même en-tête, quelle déclaration (le cas échéant) est garantie pour définir la même variable entre les unités de traduction?

par exemple.,

cexpr.h:

#ifndef CEXPR_H
#define CEXPR_H

constexpr int cint = 1;
static constexpr int scint = 1;

#endif

a.cpp:

#include "cexpr.h"

b.cpp:

#include "cexpr.h"
18
Danra

Dans votre exemple actuel, il n'y a pas de différence: sur les déclarations de variables, constexpr implique const, et une variable const à la portée de l'espace de noms a un lien interne par défaut (donc l'ajout de static ne signifie pas changer quoi que ce soit).

En C++ 14, vous ne pouvez pas déclarer une variable en tant que constexpr et lui faire associer un lien externe, sauf si vous ne le faites que dans une seule unité de traduction. La raison en est que les variables constexpr nécessitent un initialiseur, et une déclaration avec initialiseur est une définition, et vous ne devez avoir qu'une seule définition.

Cependant, ce que vous pouvez faire est d'utiliser une constante intégrale normale, que vous pouvez déclarer (pas définir) comme extern, et dans le unité de traduction où elle est définie, elle peut même être utilisée comme expression constante:

lib.h:

extern const int a;

lib.cpp:

#include "lib.h"

const int a = 10;

int b[a] = {1, 2, 3};   // OK in this translation unit

En C++ 17, il y a une nouvelle fonctionnalité "variables en ligne" qui vous permet de dire:

inline constexpr int a = 10;

Et ceci est une "définition en ligne" qui peut apparaître à plusieurs reprises, et chaque définition définit la même entité (comme toutes les autres entités "en ligne" dans le Langue).

15
Kerrek SB