Warum ruft dies den Standardkonstruktor auf?

80
struct X
{
    X()    { std::cout << "X()\n";    }
    X(int) { std::cout << "X(int)\n"; }
};

const int answer = 42;

int main()
{
    X(answer);
}

Ich hätte erwartet, dass dies auch gedruckt wird

  • X(int), weil X(answer);als Besetzung von intbis Xoder interpretiert werden könnte
  • überhaupt nichts, weil X(answer);als Deklaration einer Variablen interpretiert werden könnte.

Es wird jedoch gedrucktX() , und ich habe keine Ahnung, warum X(answer);der Standardkonstruktor aufgerufen werden soll.

BONUSPUNKTE: Was müsste ich ändern, um eine temporäre anstelle einer variablen Deklaration zu erhalten?

Fredoverflow
quelle
1
X ((int) Antwort); erzeugt jedoch das richtige Ergebnis.
Inisheer
2
@JTA Und schließlich X(int(answer));druckt nichts, weil es eine Funktionsdeklaration ist :)
Fredoverflow
1
überhaupt nichts, weil X (Antwort); könnte als Deklaration einer Variablen interpretiert werden. Diese Deklaration wäre auch eine Definition und löst die Ausführung des Standardkonstruktors aus ... was wiederum bedeutet, dass Sie Ihre eigene Frage beantwortet haben.
David Rodríguez - Dribeas
6
@ David double(expresso);, los geht's, nur für dich deklariert;)
Fredoverflow
2
@FredOverflow: Ich muss eine Definition benötigen , um es zu verwenden, weil ich keine Wirkung fühle ...
David Rodríguez - Dribeas

Antworten:

73

überhaupt nichts, weil X (Antwort); könnte als Deklaration einer Variablen interpretiert werden.

Ihre Antwort ist hier versteckt. Wenn Sie eine Variable deklarieren, rufen Sie ihren Standard-Ctor auf (wenn kein POD und all das Zeug).

Bei Ihrer Bearbeitung: Um eine temporäre zu erhalten, haben Sie einige Optionen:

Xeo
quelle
4
Das ist static_cast<X>(answer)die "meiste C ++" - Antwort - es wird sogar von einer alten GCC-Dokumentation empfohlen , um einen Wert zu erzwingen.
Kerrek SB
Wird der Klammerinitialisierer nicht möglicherweise auch eine Kopie enthalten?
Rubenvb
@rubenvb: Warum sollte es? Es ist nur eine schicke neue Art zu sagen X(answer)und garantiert einen CTOR-Anruf.
Xeo
@Xeo: Weil die Syntax des Klammerinitialisierers seine Argumente nach Wert nimmt? (<- beachten Sie das Fragezeichen)
Rubenvb
4
@KerrekSB Aber sicher erst vor C ++ 11, nein? Nun wird die kanonische Antwort sein X{answer}.
Konrad Rudolph
66

Die Klammern sind optional. Was Sie gesagt haben, ist identisch mit X answer;und es ist eine Erklärung.

Kerrek SB
quelle
9

Wenn Sie eine Variable vom Typ X deklarieren möchten, gehen Sie folgendermaßen vor:

X y(answer);
huysentruitw
quelle
1
Er fragte nicht, wie er den X(int)Ctor anrufen sollte .
Xeo
Ja, aber ich habe ein kleines Gefühl, dass es das war, was er tun wollte :)
Huysentruitw
6
@WouterH: Eigentlich ist es unwahrscheinlich, Fred zu kennen. Er ist einer von denen, die gerne die dunklen Ecken des C ++ - Standards erkunden und versuchen, ihn zu verstehen. In einem bestimmten Rollenspiel hätte er bereits alle seine Vernunftpunkte verloren;)
Matthieu M.