为什么我们在C++ 11中使用initializer_list?

Sea*_*ean 5 c++ stl initializer-list c++11

我读的initializer_list是针对单个类型的未知数量的参数的函数.但为什么我们需要呢?为什么我们不能使用普通容器,比如vectorlist

我尝试了以下代码,它的工作原理.

#include <iostream>
#include <list>
#include <string>
using namespace std;

void f(const list<string> &slst)
{
    for (auto s : slst)
        cout << s << endl;
}

int main()
{
    f({ "Good", "morning", "!" });
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Val*_*ris 7

虽然您的代码没有明确提及它,但实际上您initializer_list构造函数中list使用了:

list( std::initializer_list<T> init, 
      const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

事实上,你可能更愿意使用标准库容器接受初始化列表在它们的构造(例如std::vector,std::list)比写功能std::initializer_list参数自己.标准库中的另一个示例是聚合函数std::min,std::max它们从任意数量的输入值计算单个值.

但是,在某些情况下,您可能希望将其用于自己的函数,例如,您自己实现的数据结构的构造函数,或者您自己的聚合函数.虽然这些东西也将有可能std::vector或者std::list,用最小的开销最简单的方法是使用std::initializer_list.


Ric*_*ges 5

简而言之:

int x[3] = { 1, 2, 3 };自 C 以来就一直存在。

然而,int x[]这是有问题的,因为:

  1. 它不是类型,因此它不支持成员函数
  2. 它不可复制

现在我们有了std::array<int, 3> x = { 1, 2, 3 };which,它是一个类,所以它可以有成员函数并且是可复制的。并且它具有与 ac 数组一致的初始化符号,这是一件好事

事实证明,这也是初始化映射、集合、向量、unordered_map 等的有用方法。

实现这一点的机制是std::initializer_list<T>,它翻译了{ 1, 2, 3 }为具有大小、开始和结束的对象,以便可以遍历它。

这使得编码变得更容易、更直观。因为在c++03中,相当于这样:

std::vector<int> x = { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)

这是:

std::vector<int> make_vector()
{
  std::vector<int> result;
  result.reserve(3);
  result.push_back(1);
  result.push_back(2);
  result.push_back(3);
  return result;
};

std::vector<int> x = make_vector();
Run Code Online (Sandbox Code Playgroud)

我想你会同意这一点,完全糟糕!

  • “这不是一种类型”? (2认同)