回答
這兩種語法在大多數情況下是等價的,哪一種選擇主要是品味問題。如果你到統一的初始化,我建議做:
A a{ A{} };
否則,圓括號單獨可以用來消除:
A a((A())); // This can't be parsed as a function declaration
注意,有一種情況(可能性非常小,我必須說)在你的問題中顯示的兩種形式不相同。如果您A
類有一個構造函數的initializer_list<A>
,該構造將優於拷貝構造函數當使用大括號:
#include <initializer_list>
#include <iostream>
struct A
{
A() { }
A(std::initializer_list<A> l) { std::cout << "init-list" << std::endl; }
A(A const& a) { std::cout << "copy-ctor" << std::endl; }
};
int main()
{
A a(A{}); // Prints "copy-ctor" (or nothing, if copy elision is performed)
A b{A()}; // Prints "init-list"
}
上述差異在此live example所示。
其實,第一個*不會爲我打印「copy-ctor」。我認爲它的複製elision。 –
@MemyselfandI:對,編譯器正在刪除拷貝 - 但從概念上說,拷貝構造函數被選中 –
複製刪除僅在優化啓用時纔會發生? –
在大多數情況下它們是等效的,但A a{ A() };
將更喜歡std::initializer_list
構造函數(如果存在的話),而A a(A{});
將偏好移動/複製構造函數。
當構造器最終調用移動/複製構造函數時,可以省略新對象的構造,但對於std::initializer_list
構造函數來說這是不可能的。
兩種語法都不會被解析爲函數聲明,所以都避免了最棘手的解析。
#include <iostream>
#include <initializer_list>
struct A {
A() {
std::cout << "A()\n";
}
A(A&&) {
std::cout << "A(A&&)\n";
}
A(std::initializer_list<A>) {
std::cout << "A(std::initializer_list<A>)\n";
}
};
int main()
{
{A a{ A() };} // Prints "A()\n" "A(std::initializer_list<A>)\n"
{A a(A{});} // Prints "A()\n" and *possibly*
// (depending on copy elision) "A(A&&)\n"
}
- 1. 使用超類方法初始化與初始化方法之間的區別
- 2. 用=初始化和用{}初始化有什麼區別?
- 3. 統一和值初始化
- 4. 爲什麼統一初始化語法僅適用於對象?
- 5. 複雜層次結構中的統一初始化語法?
- 6. hybris系統初始化和更新有什麼區別?
- 7. 在下一步中聲明和初始化的初始化有什麼區別?
- 8. 對象初始化語法
- 9. 數組初始化語法
- 10. 初始化之間的區別:
- 11. C++初始化int與double的區別
- 12. 數組初始化的區別
- 13. Java中{}和{{}}初始化的區別
- 14. 初始化語句
- 15. 配置系統無法初始化
- 16. 配置系統無法初始化
- 17. 構造函數聲明和初始化的初始化之間的區別
- 18. Java中靜態初始化和動態初始化有什麼區別?
- 19. 不初始化指針並將其初始化爲null會有什麼區別?
- 20. 如何理解直接初始化和複製初始化之間的區別
- 21. 這兩種初始化PHP類的方法有什麼區別?
- 22. 這個初始化方法有什麼區別?
- 23. 這兩種類初始化方法有什麼區別?
- 24. 基本類型的統一初始化?
- 25. C++ 0x統一初始化「怪異」
- 26. 載體 - 對統一初始化
- 27. 引用的統一初始化
- 28. 用數組或初始化初始化一個NSMutableArray初始化
- 29. 構造鏈接和初始化語法
- 30. Objective-C點語法和初始化
在這種特殊情況下,最簡單的選擇是'A a;',對吧?如果我不誤解這一點,那麼當你想要傳遞給'A'的構造函數的類型與'A'類型不同時,你所建議的語法纔有意義,對嗎?即'A a {B()};'。 – jogojapan