【问题标题】:std::string(count, ch) not called when using uniform initialization使用统一初始化时未调用 std::string(count, ch)
【发布时间】:2017-05-10 21:58:27
【问题描述】:

我刚刚被这个看似无辜的尝试抓住了,该尝试使用统一的初始化语法调用std::string constructor,它接受一个大小和一个字符值:

std::string s{ 10, '\0' };

我以为这会创建一个长度为 10 的字符串,初始化为 \0

虽然它实际上调用了构造函数,该构造函数采用 initializer list 并因此创建了一个 长度为 2 的字符串,并以 {'\n', '\0'}!

进行了初始化

demo at Coliru

在使用统一初始化时,有没有办法避免这个陷阱?还是我只需要小心点?

注意:之前有人问过Similar question,但没有给出如何避免这个陷阱的答案。

【问题讨论】:

  • 我认为uniform initialization 上的维基百科条目很好地描述了它:“统一初始化不会取代构造函数语法,有时仍然需要它。如果一个类有一个初始化列表构造函数 (TypeName(initializer_list<SomeType>);) ,则它优先于其他形式的构造,前提是初始化列表符合序列构造函数的类型。”
  • @clcto 编译器似乎渴望使用初始化列表构造函数,即使列表包含不符合要求的类型 (Coliru example)。公平地说,有一个编译器警告。
  • @zett42:郑重声明,[over.match.list]/1 保证了这种行为;基本上;构造函数分两个阶段查找,如果存在任何初始化列表构造函数,那么无论好坏,这就是你得到的。

标签: c++ string c++11 uniform-initialization


【解决方案1】:

你只需要小心。

一般来说,当人们告诉您“使用统一初始化以使所有内容保持一致并且,统一”时,忽略它们。我的意思是,一定要使用统一初始化,但不要相信童话。

另外,请忽略功能的名称。

【讨论】:

  • 嗯,该功能在标准中没有正式命名为“统一初始化”(或独角兽,就此而言)。
  • 公平地说,列表初始化没有必须以这种方式进行。如果委员会没有犯两个错误,它可以包含所有形式的初始化:偏爱initializer_list 构造函数和禁止缩小转换。删除这两个,你可以合法地用{}替换任何​​()初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 2016-02-04
  • 1970-01-01
相关资源
最近更新 更多