[英]trick question regarding declaration syntax in C++
看看這里:在下面的代碼中,b的類型是什么?
struct A {
A (int i) {}
};
struct B {
B (A a) {}
};
int main () {
int i = 1;
B b(A(i)); // what would be the type of b
return 0;
}
如果有人能夠徹底向我解釋為什么會存在這樣的語法,我將不勝感激:)
謝謝。
它是根據C ++標准8.2 / 1的本地函數聲明。 您可以使用隱式構造函數來避免這種情況或以下情況:
B b(A(i)); // is equal to B b( A i );
// ---
// to declare variable of type B write:
B b = A(i);
// explicit form if you want:
B b( static_cast<A>(A(i)) );
// or
B b( (A)i );
C ++標准8.2 / 1:
函數式轉換與6.8中提到的聲明之間的相似性所產生的模糊性也可以在聲明的上下文中出現。 在該上下文中,選擇在函數聲明與參數名稱周圍的冗余括號集和具有函數樣式轉換作為初始化器的對象聲明之間。 正如6.8中提到的含糊不清一樣,決議是考慮任何可能是聲明聲明的結構。
C的一個瑕疵(和C ++繼承它(並使其變得更糟))是沒有特殊的語法來引入聲明。 這意味着聲明通常看起來像可執行代碼。 另一個例子:
A * a;
這是A乘以a,還是聲明了什么? 為了理解這一行,你必須知道A是一個類型的名稱。
C ++中的基本規則是,如果可以將某些東西解析為聲明,那么它就是。 在這種情況下,它會導致奇怪而令人驚訝的結果。 函數聲明看起來很像函數調用,特別是(在A之后可以想到幾種方式)。
您可以在此示例中使用額外的括號來解決此問題,這些括號將刪除編譯器將代碼解析為聲明的能力。
B b((A(i)));
在C中,這不是模糊的,因為沒有構造函數調用的函數樣式,因為沒有構造函數。 A是類型的名稱,或者是函數的名稱。 它不可能兩者兼而有之。
B b(A(i));
相當於
B b(A i);
- 參數名稱周圍的括號是可選的 - 相當於
B b(A);
- 參數名稱在函數聲明中是可選的。 因此它是一個函數聲明。
通常你會遇到它
X x();
- 不是預期的默認構造函數 - 但是在使用臨時工具時有更復雜的情況,例如
vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.