[英]c++ : calling constructors via curly braces?
class A
{
int value_;
public:
A(int value):value_(value){}
};
A get_a1(int value)
{
return A(value);
}
A get_a2(int value)
{
return {value};
}
int main()
{
A a1 = get_a1(1);
A a2 = get_a2(2);
}
get_a1()
和get_a2()
之間有什么區別get_a2()
如果有)?
return {value};
如何return {value};
叫? (我猜“通過花括號調用構造函數”不是指代這個的正確方法)
在你的情況下,根本沒有區別。 但是如果你稍微修改一下你的代碼,就會有明顯的不同!
首先,你可以用不同的方式構造你的類型,所有描述在這里:初始化
不同之處在於,如果您的類還提供了一個采用std::initializer_list
的構造std::initializer_list
。
請參閱以下修改/擴展的代碼以顯示差異:
class A
{
public:
A(int value):value_(value){ std::cout << "int" << std::endl;}
A(const std::initializer_list<int>& ){ std::cout << "list" << std::endl;}
void print()
{
std::cout << value_ << std::endl;
}
private:
int value_;
};
A get_a1(int value)
{
std::cout << "()" << std::endl;
return A(value);
}
A get_a2(int value)
{
std::cout << "{}" << std::endl;
return {value};
}
int main()
{
A a1 = get_a1(1);
a1.print();
A a2 = get_a2(2);
a2.print();
}
如果您運行該程序,您將看到使用{}
將使用std::initializer_list
調用構造函數,而使用()
將使用您的int
構造函數。
為什么在標准中描述:
§13.3.1.7 [over.match.list]/p1:
當非聚合類類型
T
被列表初始化 (8.5.4) 時,重載決議分兩個階段選擇構造函數:
- 最初,候選函數是類
T
的初始化列表構造函數(8.5.4),參數列表由初始化列表作為單個參數組成。- 如果找不到可行的初始化列表構造函數,則再次執行重載決議,其中候選函數是類
T
所有構造函數,參數列表由初始化列表的元素組成。如果初始值設定項列表沒有元素並且
T
具有默認構造函數,則省略第一階段。 在復制列表初始化中,如果選擇了explicit
構造函數,則初始化是格式錯誤的。
此外,初始化列表構造函數不允許縮小!
§8.5.4 列表初始化
(3.4) 否則,如果 T 是類類型,則考慮構造函數。 枚舉適用的構造函數,並通過重載決議([over.match]、[over.match.list])選擇最佳構造函數。 如果需要縮小轉換(見下文)來轉換任何參數,則程序格式錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.