簡體   English   中英

初始化列表與向量

[英]Initializer list vs. vector

在C ++ 11中,可以使用初始化列表來初始化函數中的參數。 它的目的是什么? 使用const向量不能做同樣的事情嗎? 以下兩個程序有什么區別?

使用初始化列表:

#include <iostream>

using namespace std;

int sumL(initializer_list<int> l){
    int sum = 0;
    for (const auto i: l){
        sum += i;
    }
    return sum;
}

int main(){

    cout << sumL({1, 2, 3}) << "\n";

    return 0;
}

使用const向量:

#include <iostream>
#include <vector>

using namespace std;

int sumV(const vector<int> l){
    int sum = 0;
    for (const auto i: l){
        sum += i;
    }
    return sum;
}

int main(){

    cout << sumV({1, 2, 3}) << "\n";
    return 0;
}

std::initializer_list的常見用法是作為容器(和類似)類的構造函數的參數,允許從相同類型的幾個對象方便地初始化這些容器。 當然,您可以使用std::initializer_list ,然后使用相同的{}語法。

由於std::initializer_list具有固定大小,因此不需要動態分配,因此可以有效地實現。 另一方面, std::vector需要動態內存分配。 即使在您的簡單示例中,編譯器也不太可能優化此開銷(避免中間std::vector及其動態內存分配)。 除此之外,程序的結果沒有區別(盡管你應該使用const std::vector<int>& argument來避免副本及其相關的動態內存分配)。

兩者的語義完全不同。 initializer_list具有指針語義,而vector具有值語義。

在第一個示例中,編譯器將生成類似於以下內容的代碼:

int const __temp_array[3] = {1, 2, 3};
cout << sumL(std::initializer_list<int>(__temp_array, __temp_array + 3)) << "\n";

這在[dcl.init.list] / 5中有解釋。 如您所見,在sumL您可以訪問指向sumL -init-list元素的const指針,這意味着您沒有其他選項,只能將元素復制到列表中。

sumV情況下,如果需要,你可以std::moved vector的元素(假設參數類型不是const )。

類似地,復制initializer_list執行淺拷貝,即僅復制指針,而復制vector當然意味着將復制元素。

在您的示例中,上述任何一點都沒有任何區別,除了構造vector將需要動態內存分配,而構造initializer_list則不會。

initializer_list使用最佳存儲位置並防止不必要的調用,它被設計為輕量級,而對於vector有一個堆分配,可能會有更多的副本/移動。

initalizer_list不是像std :: vector這樣的通用容器。 它的主要目的是對象初始化。 如果低聽不到,沒有堆分配對你有吸引力,我建議你看一下std :: array。 它是一個固定大小的堆棧分配數組,具有STL容器的所有便利,它本質上是一個在c數組頂部的薄包裝器。

暫無
暫無

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

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