La declaración de un objeto const en C ++ requiere un constructor predeterminado definido por el usuario. Si tengo una variable miembro mutable, ¿por qué no?

8

En C ++, para declarar un objeto de una clase que tiene una variable miembro como const, debemos tener un constructor predeterminado definido por el usuario. El siguiente código ilustra esto.

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;
}

Sin embargo, si una variable miembro propiedad de una clase se califica como mutable, el compilador no informará ningún error. Como referencia, compilé usando el comando clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug. Me pregunto si este resultado se debe a un error en el compilador o de acuerdo con la sintaxis definida en el lenguaje C ++.

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}
Jinbeom Hong
fuente
2
mutablees un poco lo contrario de const. ¿Por qué esperabas el mismo efecto?
idclev 463035818
2
Porque no tiene sentido inicializar un objeto en a const, lo que significa que no se puede cambiar y que tiene valores no inicializados, no hay uso para este tipo de código y es por eso que está prohibido. Cuando usa la mutablepalabra clave, significa que el valor se puede cambiar más tarde, por lo que el código se puede usar de manera predecible.
Moshe Gottlieb
44
@¿Lo hace? Los OP ya saben que el primer fragmento está mal formado, se preguntan por qué clang acepta el segundo sin ningún diagnóstico.
Bob__

Respuestas:

2

Reescribiendo mi comentario como respuesta, espero que pueda ayudar a alguien.

No tiene sentido declarar un objeto constante si no se inicializa de alguna forma.
Considere el siguiente código:

    const int x;

tañido dice: error: default initialization of an object of const type 'const int'.
gcc diría:error: uninitialized const ‘x’ [-fpermissive]

La lógica detrás de esto es que no tiene sentido este tipo de declaración.
El valor de xnunca puede cambiar y, por lo tanto, este código sería impredecible, ya xque se asignaría a la memoria no inicializada.
En su ejemplo, la adición de la palabra clave mutableque valuesignifica que aunque el Someejemplo es constante cuando se declara como:

    const Some some;

Todavía es posible cambiar valueen un momento posterior.
Por ejemplo:

    some.value = 8;

Esto significa que es posible usar este código de manera predecible, ya que valuese puede configurar más tarde y no hay constantes no inicializadas.

Moshe Gottlieb
fuente
Si es así, ¿podemos determinar que hay un error en gcc? Cuando compilo el programa con gcc, informa un error a pesar de que las variables miembro son mutables.
Jinbeom Hong
1
Lo siento @jinbeomhong, no lo sé. Solo puedo adivinar que el equipo de gcc interpreta el estándar de manera diferente.
Moshe Gottlieb
De todos modos, solo necesitaba razones lógicas para entender que estos resultados estaban llegando, y para seguir su lógica, creo que clang ++ juzgó racionalmente la sintaxis. Gracias.
Jinbeom Hong