Das Deklarieren eines const-Objekts in C ++ erfordert einen benutzerdefinierten Standardkonstruktor. Wenn ich eine veränderbare Mitgliedsvariable habe, warum nicht?

8

In C ++ benötigen constwir einen benutzerdefinierten Standardkonstruktor , um ein Objekt einer Klasse mit einer Mitgliedsvariablen als zu deklarieren . Der folgende Code veranschaulicht dies.

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

Wenn jedoch eine Mitgliedsvariable, die einer Klasse gehört, als veränderbar qualifiziert ist, meldet der Compiler keine Fehler. Als Referenz habe ich mit dem Befehl kompiliert clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug. Ich frage mich, ob dieses Ergebnis auf einen Fehler im Compiler oder auf die in der C ++ - Sprache definierte Syntax zurückzuführen ist.

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}
Jinbeom Hong
quelle
2
mutableist das Gegenteil von const. Warum haben Sie den gleichen Effekt erwartet?
idclev 463035818
2
Da es keinen Sinn macht, ein Objekt mit a zu initialisieren const, was bedeutet, dass es nicht geändert werden kann und dass es nicht initialisierte Werte hat, gibt es keine Verwendung für diese Art von Code und deshalb ist es verboten. Wenn Sie das mutableSchlüsselwort verwenden, bedeutet dies, dass der Wert später geändert werden kann, sodass der Code auf vorhersehbare Weise verwendet werden kann.
Moshe Gottlieb
4
@Macht es? Die OP sind sich bereits bewusst, dass das erste Snippet schlecht geformt ist. Sie fragen sich, warum Clang das zweite ohne Diagnose akzeptiert.
Bob__

Antworten:

2

Ich schreibe meinen Kommentar als Antwort um und hoffe, er könnte jemandem helfen.

Es macht keinen Sinn, ein const-Objekt zu deklarieren, wenn es nicht in irgendeiner Form initialisiert ist.
Betrachten Sie den folgenden Code:

    const int x;

Clang sagt : error: default initialization of an object of const type 'const int'.
gcc würde sagen:error: uninitialized const ‘x’ [-fpermissive]

Die Logik dahinter ist, dass diese Art der Deklaration keinen Sinn hat .
Der Wert von xkann sich niemals ändern, und daher wäre dieser Code unvorhersehbar, da er xeinem nicht initialisierten Speicher zugeordnet würde.
In Ihrem Beispiel bedeutet das Hinzufügen des Schlüsselworts mutablezu value, dass die SomeInstanz zwar konstant ist, wenn sie wie folgt deklariert wird:

    const Some some;

Es ist noch möglich, valuezu einem späteren Zeitpunkt zu ändern .
Zum Beispiel:

    some.value = 8;

Dies bedeutet, dass es möglich ist, diesen Code auf vorhersehbare Weise zu verwenden, da value später festgelegt werden kann und keine nicht initialisierten Konstanten vorhanden sind.

Moshe Gottlieb
quelle
Wenn ja, können wir feststellen, dass es einen Fehler in gcc gibt? Wenn ich das Programm mit gcc kompiliere, meldet es einen Fehler, obwohl die Mitgliedsvariablen veränderbar sind.
Jinbeom Hong
1
Sorry @jinbeomhong - ich weiß es nicht. Ich kann nur vermuten, dass das gcc-Team den Standard anders interpretiert.
Moshe Gottlieb
Wie auch immer, ich brauchte nur logische Gründe, um zu verstehen, dass diese Ergebnisse kommen würden, und um Ihrer Logik zu folgen, denke ich, dass clang ++ die Syntax rational beurteilt hat. Vielen Dank.
Jinbeom Hong