简体   繁体   English

初始化列表与向量

[英]Initializer list vs. vector

In C++11, one can use initializer lists to initialize parameters in functions. 在C ++ 11中,可以使用初始化列表来初始化函数中的参数。 What is the purpose of it? 它的目的是什么? Can't the same be done with const vectors? 使用const向量不能做同样的事情吗? What is the difference of the two programs below? 以下两个程序有什么区别?

Using an initializer list: 使用初始化列表:

#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;
}

Using a const vector: 使用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;
}

The common use of std::initializer_list is as argument to constructors of container (and similar) classes, allowing convenient initialisation of those containers from a few objects of the same type. std::initializer_list的常见用法是作为容器(和类似)类的构造函数的参数,允许从相同类型的几个对象方便地初始化这些容器。 Of course, you can use std::initializer_list otherwise and then use the same {} syntax. 当然,您可以使用std::initializer_list ,然后使用相同的{}语法。

Since a std::initializer_list has a fixed size, it doesn't require dynamic allocation and hence can be efficiently implemented. 由于std::initializer_list具有固定大小,因此不需要动态分配,因此可以有效地实现。 A std::vector , on the other hand, requires dynamic memory allocation. 另一方面, std::vector需要动态内存分配。 Even in your simple example it is unlikely that the compiler will optimize this overhead away (avoid the intermediary std::vector and its dynamic memory allocation). 即使在您的简单示例中,编译器也不太可能优化此开销(避免中间std::vector及其动态内存分配)。 Other than that, there is no difference in the outcome of your programs (though you should take a const std::vector<int>& argument to avoid a copy and its associated dynamic memory allocation). 除此之外,程序的结果没有区别(尽管你应该使用const std::vector<int>& argument来避免副本及其相关的动态内存分配)。

The semantics of the two are quite different. 两者的语义完全不同。 The initializer_list has pointer semantics while the vector has value semantics. initializer_list具有指针语义,而vector具有值语义。

In your first example, the compiler will generate code similar to the following: 在第一个示例中,编译器将生成类似于以下内容的代码:

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

This is explained in [dcl.init.list]/5 . 这在[dcl.init.list] / 5中有解释。 As you can see, within sumL you have access to const pointers to the elements of the braced-init-list , this means you have no other option but to copy the elements out of the list. 如您所见,在sumL您可以访问指向sumL -init-list元素的const指针,这意味着您没有其他选项,只能将元素复制到列表中。

In case of sumV you could've std::moved the elements from the vector if needed (assuming the parameter type is not const ). sumV情况下,如果需要,你可以std::moved vector的元素(假设参数类型不是const )。

Similarly, copying the initializer_list performs shallow copies, ie only the pointers will be copied, while copying the vector , of course, means the elements will be copied. 类似地,复制initializer_list执行浅拷贝,即仅复制指针,而复制vector当然意味着将复制元素。

In your example, none of the points above really make any difference, other than constructing the vector will require dynamic memory allocation, while constructing the initializer_list will not. 在您的示例中,上述任何一点都没有任何区别,除了构造vector将需要动态内存分配,而构造initializer_list则不会。

initializer_list使用最佳存储位置并防止不必要的调用,它被设计为轻量级,而对于vector有一个堆分配,可能会有更多的副本/移动。

initalizer_list is not a generalized container like std::vector. initalizer_list不是像std :: vector这样的通用容器。 It's primary purpose is object initialization. 它的主要目的是对象初始化。 If the low overheard and no heap allocation is attractive to you I'd suggest looking at std::array. 如果低听不到,没有堆分配对你有吸引力,我建议你看一下std :: array。 It a fixed sized stack allocated array that has all the conveniences of a STL container, which is essentially a thin wrapper on top of a c-array. 它是一个固定大小的堆栈分配数组,具有STL容器的所有便利,它本质上是一个在c数组顶部的薄包装器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM