Antes do C ++ 11, só podíamos realizar a inicialização em classe em membros const estáticos do tipo integral ou enumeração. Stroustrup discute isso em seu C ++ FAQ , dando o seguinte exemplo:
class Y {
const int c3 = 7; // error: not static
static int c4 = 7; // error: not const
static const float c5 = 7; // error: not integral
};
E o seguinte raciocínio:
Então, por que essas restrições inconvenientes existem? Uma classe é normalmente declarada em um arquivo de cabeçalho e um arquivo de cabeçalho é normalmente incluído em muitas unidades de tradução. No entanto, para evitar regras complicadas de vinculador, C ++ exige que cada objeto tenha uma definição exclusiva. Essa regra seria quebrada se o C ++ permitisse a definição em classe de entidades que precisavam ser armazenadas na memória como objetos.
No entanto, o C ++ 11 relaxa essas restrições, permitindo a inicialização em classe de membros não estáticos (§12.6.2 / 8):
Em um construtor não delegante, se um determinado membro de dados não estáticos ou classe base não for designado por um mem-initializer-id (incluindo o caso em que não há mem-initializer-list porque o construtor não tem ctor-initializer ) e a entidade não é uma classe base virtual de uma classe abstrata (10.4), então
- se a entidade for um membro de dados não estático que possui um inicializador de chave ou igual , a entidade será inicializada conforme especificado em 8.5;
- caso contrário, se a entidade for um membro variante (9.5), nenhuma inicialização é realizada;
- caso contrário, a entidade é inicializada por padrão (8.5).
A seção 9.4.2 também permite a inicialização em classe de membros estáticos não constantes se eles estiverem marcados com o constexpr
especificador.
Então, o que aconteceu com as razões para as restrições que tínhamos em C ++ 03? Simplesmente aceitamos as "regras complicadas do vinculador" ou alguma outra coisa mudou que torna isso mais fácil de implementar?