为什么初始值设定项列表与表达式列表的结果不同
Why does initializer-list have different result compared with expression-list
当我在下面写一些代码时,我觉得很奇怪。我期待着相同的输出,但事实证明这是错误的。为什么 2 个语句的输出不同,(表达式列表(和 {初始值设定项列表} 有什么区别?
cout << string(4, 'c') << endl;
cout << string{ 4, 'c' } << endl;
输出为:
cccc
c //a square '' before 'c'
从 cppreference.com:
否则,
T
的构造函数将分两个阶段进行考虑:
将检查将
std::initializer_list
作为唯一参数或作为第一个参数(如果其余参数具有默认值(的所有构造函数,并通过针对类型std::initializer_list
的单个参数的重载解析进行匹配如果前一阶段未生成匹配项,则
T
的所有构造函数都参与针对由大括号 init-list元素组成的参数集的重载解析,但限制是只允许非收缩转换。如果此阶段生成显式构造函数作为复制列表初始化的最佳匹配项,则编译将失败(注意,在简单的复制初始化中,根本不考虑显式构造函数(。
在您的情况下
string(4, 'c')
使用以下构造函数。
std::string(size_type count,
char ch,
const Allocator& alloc = Allocator() );
另一方面
string{ 4, 'c' }
使用以下构造函数。
std::string(std::initializer_list<char> ilist,
const Allocator& alloc = Allocator() );
如果第二个构造函数没有在std::string
中定义,这两个构造函数将产生相同的对象。
两者都是构造函数调用,但它们调用两个不同的构造函数。第一次调用(链接中的"2"(使用字符计数构造,因此在您的情况下你会得到 4 个'c。
第二个构造函数(链接中的"9"(采用std::initializer_list
。当您使用大括号而不是参数进行构造时,如果类的构造函数采用initializer_list则它将始终优先。
如果有什么安慰的话,多年来,这种行为已经难倒了很多程序员......
相关文章:
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 概念中的cv限定符需要表达式参数列表
- C++模板函数中的初始化 - 新的初始值设定项表达式列表被视为复合表达式
- 使用正则表达式获取大括号块的列表
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- 列表.erase 中的 lambda 表达式
- 为什么初始值设定项列表与表达式列表的结果不同
- 将任何类型的表达式放在 c++ 的初始化列表中在语法上是否正确?
- C++ 包含表达式的初始化列表
- 射击时从列表中删除外星人 - 找出循环;"表达式:无法递增结束列表迭代器"
- 使用 STD 正则表达式标记逗号分隔的列表
- C 套接字误差(新的初始器表达式列表被视为复合表达式)
- 错误:表达式列表在初始化器[-fpermissive] Double Paycalc(p,yir,y)中被视为复合表达式
- 可变模板:表达式列表在函数转换错误中被视为复合表达式
- 为什么 lambda 表达式的捕获列表无法使用结构化绑定分解
- Makefile中扩展正则表达式列表的分隔符
- 表达式列表被视为复合表达式
- boost正则表达式中的命名捕获/组列表
- 正在转发初始值设定项列表表达式
- 编写布尔表达式以判断列表是否在增加