Declarar um objeto const em C ++ requer um construtor padrão definido pelo usuário. Se eu tenho uma variável de membro mutável, por que não?

8

No C ++, para declarar um objeto de uma classe que possui uma variável de membro como const, precisamos ter um construtor padrão definido pelo usuário. O código a seguir ilustra isso.

class Some {
    int value;
};

int main() {
    // error: default initialization of an object of const type 'const Some'
    //        without a user-provided default constructor
    const Some some;

    return 0;
}

No entanto, se uma variável de membro pertencente a uma classe for qualificada como mutável, o compilador não relatará nenhum erro. Para referência, eu compilado usando o comando clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug. Gostaria de saber se este resultado é devido a um erro no compilador ou de acordo com a sintaxe definida na linguagem C ++.

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}
jinbeom hong
fonte
2
mutableé o oposto de const. Por que você esperava o mesmo efeito?
idclev 463035818 21/01
2
Como não faz sentido inicializar um objeto para a const, o que significa que ele não pode ser alterado e, com valores não inicializados, não há utilidade para esse tipo de código e é por isso que é proibido. Quando você usa a mutablepalavra-chave - significa que o valor pode ser alterado posteriormente, para que o código possa ser usado de maneira previsível.
Moshe Gottlieb
4
@Faz? Os OP já sabem que o primeiro trecho está mal formado e se perguntam por que o clang aceita o segundo sem nenhum diagnóstico.
Bob__

Respostas:

2

Reescrevendo meu comentário como resposta, espero que ajude alguém.

Não faz sentido declarar um objeto const se não for inicializado de alguma forma.
Considere o seguinte código:

    const int x;

clang diz: error: default initialization of an object of const type 'const int'.
o gcc diria:error: uninitialized const ‘x’ [-fpermissive]

A lógica por trás disso é que não há sentido nesse tipo de declaração.
O valor de xnunca pode mudar e, portanto, esse código seria imprevisível, pois xseria mapeado para a memória não inicializada.
No seu exemplo, adicionar a palavra mutable- chave a valuesignifica que, embora a Someinstância seja constante quando declarada como:

    const Some some;

Ainda é possível mudar valueposteriormente.
Por exemplo:

    some.value = 8;

Isso significa que é possível usar esse código de maneira previsível, pois valuepode ser definido posteriormente e não há constantes não inicializadas.

Moshe Gottlieb
fonte
Em caso afirmativo, podemos determinar que há um erro no gcc? Quando eu compilo o programa com o gcc, ele relata um erro mesmo que as variáveis ​​de membro sejam mutáveis.
jinbeom hong 22/01
1
Desculpe @jinbeomhong - eu não sei. Só posso supor que a equipe do gcc interpreta o padrão de maneira diferente.
Moshe Gottlieb
Enfim, eu só precisava de razões lógicas para entender que esses resultados estavam chegando e, para seguir sua lógica, acho que o clang ++ julgou racionalmente a sintaxe. Obrigado.
jinbeom hong 22/01