Hier ein Stück C ++ - Code.
In diesem Beispiel sehen viele Codeblöcke wie Konstruktoraufrufe aus. Blockcode 3 ist dies leider nicht (Sie können ihn mit https://godbolt.org/z/q3rsxn und https://cppinsights.io überprüfen ).
Ich denke, es ist eine alte C ++ - Notation und könnte die Einführung der neuen C ++ 11-Konstruktionsnotation mit {} erklären (vgl. # 4).
Haben Sie eine Erklärung für die T(i)
Bedeutung, die einer Konstruktornotation so nahe kommt, aber definitiv so anders ist?
struct T {
T() { }
T(int i) { }
};
int main() {
int i = 42;
{ // #1
T t(i); // new T named t using int ctor
}
{ // #2
T t = T(i); // new T named t using int ctor
}
{ // #3
T(i); // new T named i using default ctor
}
{ // #4
T{i}; // new T using int ctor (unnamed result)
}
{ // #5
T(2); // new T using int ctor (unnamed result)
}
}
NB: somit ist T(i)
(# 3) äquivalent zu T i = T()
;
-Wall
und Sie erhalten "warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'i' [-Wvexing-parse]
" von clang oder das etwas weniger motivierte "warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
" von gcc .T t()
), aber nicht für so einfache Deklarationsausdrücke. Dies könnte sicherlich ärgerlich sein .Antworten:
Die Aussage:
ist äquivalent zu:
Mit anderen Worten, es wird eine Variable mit dem Namen
i
type deklariertT
. Dies liegt daran, dass in Deklarationen an einigen Stellen Klammern zulässig sind (um die Bindung von Deklaratoren zu ändern). Da diese Anweisung als Deklaration analysiert werden kann, handelt es sich um eine Deklaration (auch wenn sie als Ausdruck möglicherweise sinnvoller ist).quelle
int(i)
auch einint
Name deklariert wirdi
?Mit dem Compiler-Explorer können Sie sehen, was im Assembler passiert.
Sie können sehen, dass # 1, # 2 # 4 und # 5 dasselbe tun, aber seltsamerweise # 3 den anderen Konstruktor (den Basisobjektkonstruktor) aufrufen.
Hat jemand eine Erklärung?
Assembler-Code:
quelle