簡體   English   中英

為什么在創建對象時使用大括號,如果一個構造函數具有初始化列表,則調用 2 個構造函數

[英]Why does using curley braces when creating an object, calls 2 constructor if one constructor have initializer list

我碰巧遇到了這個,但我不明白,為什么Foo c{a}調用了 2 個構造函數。 我知道每一個對象被創建時,構造函數,被調用,那么為什么它被稱為foo(std::initializer_list<Foo>)即使他不這樣做Foo c{{a}}Foo c({a}) ?

 struct Foo { Foo() {} Foo(std::initializer_list<Foo>) { std::cout << "initializer list" << std::endl; } Foo(const Foo&) { std::cout << "copy ctor" << std::endl; } }; int main() { Foo a; Foo b(a); // copy ctor Foo c{a}; // copy ctor (init. list element) + initializer list!!! }

如果我們查看https://en.cppreference.com/w/cpp/language/direct_initialization

在這里我們看到:

T 對象 { arg }; (2)(C++11 起)

  1. 使用單個花括號括起來的初始化程序初始化非類類型的對象(注意:對於類類型和花括號初始化列表的其他用途,請參閱列表初始化

https://en.cppreference.com/w/cpp/language/list_initialization 中有以下項目符號:

如果 T 是一個聚合類並且初始化器列表有一個相同或派生類型的元素(可能是 cv 限定的),則從該元素初始化對象(通過復制列表初始化的復制初始化,或通過直接-直接列表初始化的初始化)。 (C++14 起)

並返回到直接初始化:

檢查 T 的構造函數並通過重載決議選擇最佳匹配。 然后調用構造函數來初始化對象。

所以,似乎在這種情況下,clang 調用復制構造函數是正確的,而 GCC 是錯誤的。 至少從 C++14 開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM