[英]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.