Avant C ++ 11, nous ne pouvions effectuer une initialisation en classe que sur des membres const statiques de type intégral ou énumération. Stroustrup en parle dans sa FAQ C ++ , en donnant l'exemple suivant:
class Y {
const int c3 = 7; // error: not static
static int c4 = 7; // error: not const
static const float c5 = 7; // error: not integral
};
Et le raisonnement suivant:
Alors, pourquoi ces restrictions peu pratiques existent-elles? Une classe est généralement déclarée dans un fichier d'en-tête et un fichier d'en-tête est généralement inclus dans de nombreuses unités de traduction. Cependant, pour éviter les règles compliquées de l'éditeur de liens, C ++ exige que chaque objet ait une définition unique. Cette règle serait rompue si C ++ autorisait la définition en classe d'entités qui devaient être stockées en mémoire en tant qu'objets.
Cependant, C ++ 11 assouplit ces restrictions, permettant l'initialisation en classe des membres non statiques (§12.6.2 / 8):
Dans un constructeur non délégant, si un membre de données non statique donné ou une classe de base n'est pas désigné par un mem-initializer-id (y compris le cas où il n'y a pas de mem-initializer-list car le constructeur n'a pas d' initialiseur ctor ) et l'entité n'est pas une classe de base virtuelle d'une classe abstraite (10.4), alors
- si l'entité est un membre de données non statique qui a un initialiseur d'accolade ou d'égalité , l'entité est initialisée comme spécifié en 8.5;
- sinon, si l'entité est un membre variant (9.5), aucune initialisation n'est effectuée;
- sinon, l'entité est initialisée par défaut (8.5).
La section 9.4.2 permet également l'initialisation en classe des membres statiques non const s'ils sont marqués avec le constexpr
spécificateur.
Alors, qu'est-il arrivé aux raisons des restrictions que nous avions dans C ++ 03? Acceptons-nous simplement les "règles compliquées de l'éditeur de liens" ou y a-t-il autre chose qui a changé qui facilite la mise en œuvre?