首頁 > 後端開發 > C++ > 我們可以安全地從 C 中的 `std::initializer_list` 中移動元素嗎?

我們可以安全地從 C 中的 `std::initializer_list` 中移動元素嗎?

Mary-Kate Olsen
發布: 2024-12-19 15:03:15
原創
328 人瀏覽過

Can We Safely Move Elements from a `std::initializer_list` in C  ?

從std::initializer_list 移動元素

在C 中,一個初始化器列表,表示為std::initializer_list,提出了一個關於其元素移動的問題元素。我們可以安全地從這樣的清單中提取和移動元素嗎?讓我們研究一下這個問題。

在下面的程式碼片段中,函數foo 接受一個初始化清單作為參數:

#include <initializer_list>
#include <utility>

template<typename T>
void foo(std::initializer_list<T> list)
{
    for (auto it = list.begin(); it != list.end(); ++it)
    {
        bar(std::move(*it)); // Intended to move the element
    }
}
登入後複製

出現這個問題是因為std::initializer_list表現出區別於普通容器的獨特特徵。它的元素駐留在臨時緩衝區中,並且不受與標準容器相同的值語義的約束。這引發了人們對成功移動的潛力的懷疑。

不幸的是,無縫元素移動的期望是沒有根據的。嘗試從初始值設定項清單中移動元素將產生意外結果。不是重新定位元素,而是建立副本。此行為源自於 std::initializer_list 中的 begin 和 end 函式。傳回 const T *,這會產生一個不可變的右值引用,表示為 T const &&。

因此,bar(std::move(*it)) 中使用的移動表達式綁定到 T 類型的函數參數const &,有效地保留了副本。

此限制的原因歸因於編譯器實例化的特權std::initializer_list 作為靜態初始化常數。允許從開始到結束的可變結果會阻礙這種最佳化,從而在編譯器的設計中引入複雜性。

儘管出現了意外的行為,但解決方案可能即將出現。 [ISO 提案](https://github.com/CaseyCarter/iso-changes/blob/master/icpp/p1716r4.md) 旨在引入對僅移動類型的初始值設定項清單支援。這項工作旨在增強語言的功能,並提供更一致的方法來處理初始化列表和移動語義。

以上是我們可以安全地從 C 中的 `std::initializer_list` 中移動元素嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板