当我在下面写一些代码时,我觉得很奇怪。我期待着相同的输出,但事实证明这是错误的。为什么 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则它将始终优先。
如果有什么安慰的话,多年来,这种行为已经难倒了很多程序员......