簡體   English   中英

`T array[N]{}` 是值初始化還是聚合初始化?

[英]Is `T array[N]{}` a value initialization or aggregate initialization?

考慮一些類型T (為簡單起見,您可以假設為int )和一些整數常量N ,我們用它來定義這樣的數組:

T array[N]{}; // Note the empty braces here!

根據cppreference ,值初始化定義如下:

這是在使用空初始化器構造 object 時執行的初始化。

但再往下寫:

在所有情況下,如果使用空括號 {} 並且 T 是聚合類型,則執行聚合初始化而不是值初始化。

但是再往下一點,出現如下語句:

  1. 如果 T 是數組類型,則數組的每個元素都被值初始化;

據我了解,第一個和第三個引用的陳述與第二個引用的陳述相矛盾。

所以我的兩個問題是:

  • 上面的代碼片段是值初始化還是聚合初始化?
  • 引用的三個陳述真的相互矛盾還是我遺漏了什么?

注意:我在這里看到過類似的問題,但它們在細節上都有所不同。

T array[N]{}是值初始化還是聚合初始化?

它是列表初始化,並且此初始化過程的一部分涉及根據dcl.init.list進行聚合初始化 此外,它也是下面引用的直接列表初始化

1 )列表初始化是 object 的初始化或來自花括號初始化列表的引用。 這樣的初始化器稱為初始化器列表,初始化器列表的逗號分隔的初始化器子句或指定初始化器列表的指定初始化器子句稱為初始化器列表的元素。 初始化列表可能為空。 列表初始化可以發生在直接初始化或復制初始化上下文中; 直接初始化上下文中的列表初始化稱為直接列表初始化,而復制初始化上下文中的列表初始化稱為復制列表初始化。

[注1:可以使用List-initialization

(1.1)作為變量定義中的初始值設定項 ([dcl.init])

...

——尾注]

以上意味着T array[N]{}是列表初始化。


現在讓我們繼續討論數組的元素是如何初始化的,這在dcl.init.list#3中給出:

3) object 或類型 T 的引用的列表初始化定義如下:

3.4)否則,如果T是聚合,則執行聚合初始化。

並且由於在我們的例子中T array[N]是一個聚合,上面暗示在我們的例子中數組T array[N]的整個初始化過程都涉及聚合初始化


最后,從下面給出的聚合初始化中,我們會注意到每個元素都是從一個空的初始化列表中復制初始化的:

3)當聚合由[dcl.init.list]中指定的初始化列表初始化時,初始化列表的元素被視為聚合元素的初始化。 聚合的顯式初始化元素確定如下

3.3)否則,初始化列表必須是{},並且沒有顯式初始化的元素。


以上意味着我們的示例中沒有顯式初始化的元素,因此我們轉到dcl.init.aggr#5

5)對於非聯合聚合,每個不是顯式初始化元素的元素初始化如下

5.2)否則,如果元素不是引用,則從空的初始化列表復制初始化元素

(強調我的)

本質上,這意味着數組中每個類型為T的元素都將從一個空的初始化列表中初始化。


請注意,這也解釋了為什么以下人為設計的示例在 C++20 中失敗

struct T
{
    T() = delete;
};
int main() 
{
    T array[5]{}; //this fails as a consequence of above explanation
}

暫無
暫無

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

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