std::initializer_list构造函数除了用值填充一些容器之外,还有什么用

What are std::initializer_list constructors used for, except for filling some container with values?

本文关键字:什么 填充 list initializer 构造函数 std      更新时间:2023-10-16

标准库中的一个主要而明显的含义是"用元素列表初始化集合":

std::vector<int> v = {1, 2, 3};

另一个含义可以在下面std::bitset上的链接后面找到——"单个值是由initializer_list的元素组装而成的"。

标准库中的第三个例子是std::piecewise_stant_distribution,但我不太确定它有什么语义,而不是一个元素集合。

std::initializer_list构造函数的其他用例是什么?如果可能的话,用真实代码中的例子。

这实际上是一个关于课堂设计的问题
由于列表初始化的一些特殊性,在现有的类中添加std::initializer_list构造函数很容易成为一个令人惊讶的突破性变化,因此在编写新类时,您应该始终提前知道它是否需要std::initializer_list构造函数
因此,我试图通过编写std::initializer_list构造函数的用例来模拟看到未来的能力。

主要的问题是:我如何确定我的类将来可能会有std::initializer_list构造函数(这对用户来说并不奇怪)来编写正确的非std::initializer_list构造函数?

我在当前的项目中实际使用了这种技术。我有一个类"BaseMenu",它需要在构造函数中初始化std::vector,所以它有std::vector作为参数。然后,我有继承自BaseMenu的MainMenu,我只告诉BaseMenu我想要我的MainMenu是什么样子:

BaseMenu(std::vector<std::string>);
MainMenu::MainMenu():
    BaseMenu({{"Play"},
              {"Options"},
              {"About"},
              {"Quit"}})

它真的很"舒服"。PS:上面的模型被简化了,但它应该给人一种std::initializer_list 的有用感

我认为initializer_list具有以下关键功能:

  1. 它将初始化概念封装在一个类中
  2. 该机制还提供了类型安全性,并避免了可能导致的任何转换信息丢失
  3. 它提供了唯一的const_iterator类型接口,因此可以对其进行读取优化,并且任何主体都不能对其进行更新/写入。这是有意义的,因为它旨在初始化其他对象

例如,您可能想参考我的博客和ISOCPP信息。

编辑

std::initializer_list 的可能优点

//1. Initialization Concept In A class
std::initializer_list<int>  x{1,2,3,4,5};
std::vector<int> v(x.begin(), x.end());


//2.Better Type Safety and avoid narrow conversions scenario
 std::vector<int> v{1, 2, 3.4, 4};
 Compiler Output
 narrowing conversion of ‘3.3999999999999999e+0’ from ‘double’ to ‘int’ inside { }

//3. Provide Const iterator type interface
std::initializer_list<int> ly{1,2,3,4,5};
auto itrs = ly.begin();
int* x = itrs;
Compiler Output
error: invalid conversion from ‘const int*’ to ‘int*’