![](/img/trans.png)
[英]No initializer list vs. initializer list with empty pairs of parentheses
[英]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.