簡體   English   中英

C++14 中 std::intializer_list 對象的預期生命周期是多少?

[英]What is expected lifetime of std::intializer_list object in C++14?

請考慮這個簡化的程序:

#include <iostream>

struct A
{
    A() { std::cout << "A() "; }
    ~A() { std::cout << "~A() "; }
};

int main()
{
    auto l = std::initializer_list<A>{A()};
    std::cout << ". ";
}

https://gcc.godbolt.org/z/1GWvGfxne

GCC在這里打印

A() . ~A()

這意味着std::initializer_list在范圍結束時被破壞。

叮當印:

A() ~A() . 

在構造它的行中銷毀std::initializer_list

兩個編譯器都在這里正確運行還是其中一個是錯誤的?

這是微妙的。

std::initializer_list由底層數組(由編譯器生成)支持。 這個數組就像一個臨時對象,而std::initializer_list是一種綁定到它的引用類型。 因此,只要“引用”存在,它就會延長臨時數組的生命周期。

在 C++14 中,我們不保證復制省略。 所以應該發生的事情就像std::initializer_list<A>{A()}產生了一個臨時的initializer_list ,綁定了另一個臨時數組,並將臨時的initializer_list復制到l

就生命周期延長而言, std::initializer_list行為類似於常規引用。 只有原始引用會延長生命周期,而我們的原始引用本身是臨時的。 因此,在包含l初始化的完整表達式的末尾,底層數組不存在。 Clang 是正確的。

直接初始化...

std::initializer_list<A> l {A()};

...在兩個編譯器上產生相同的輸出

同時,在為 C++17 編譯時,您的原始代碼在 GCC 和 Clang 上的行為相同。

根據cppreference

在 CWG 問題 1696 解決之前,允許臨時對象綁定到構造函數初始值設定項列表中的引用成員,並且它僅持續到構造函數退出,而不是只要對象存在。 自 CWG 1696 以來,這種初始化的格式不正確,盡管許多編譯器仍然支持它(一個值得注意的例外是 clang)。

暫無
暫無

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

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