Oto kawałek kodu C ++.
W tym przykładzie wiele bloków kodu wygląda jak wywołania konstruktora. Niestety, kod blokowy nr 3 nie jest (możesz to sprawdzić za pomocą https://godbolt.org/z/q3rsxn i https://cppinsights.io ).
Myślę, że jest to stara notacja C ++, która mogłaby wyjaśnić wprowadzenie nowej notacji konstrukcyjnej C ++ 11 za pomocą {} (por. 4).
Czy masz wyjaśnienie T(i)
znaczenia, tak bliskie notacji konstruktora, ale zdecydowanie tak różne?
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: w ten sposób T(i)
(# 3) jest równoważne T i = T()
;
-Wall
i otrzymasz „warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'i' [-Wvexing-parse]
” z clang lub nieco mniej „warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
” motywacji z gcc .T t()
), Ale nie o tak prostych wyrażeniach deklaracyjnych. Na pewno może to być irytujące .Odpowiedzi:
Twierdzenie:
jest równa:
Innymi słowy, deklaruje zmienną o nazwie
i
typeT
. Wynika to z faktu, że w niektórych miejscach dozwolone są nawiasy w deklaracjach (w celu zmiany powiązania deklaratorów), a ponieważ instrukcja ta może być analizowana jako deklaracja, jest to deklaracja (chociaż może mieć większy sens jako wyrażenie).źródło
int(i)
również deklarujeint
nazwęi
?Możesz użyć Eksploratora kompilatorów, aby zobaczyć, co dzieje się w asemblerze.
Widać, że # 1, # 2 # 4 i # 5 robią to samo, ale dziwnie # 3 wywołują drugi konstruktor (konstruktor obiektów podstawowych).
Czy ktoś ma wyjaśnienie?
Kod asemblera:
źródło