当我在下面编写一些代码时,我感到很奇怪。我期待相同的输出,但结果证明是错误的。为什么2个语句具有不同的输出,(expression-list)和{initializer-list}之间有什么区别?
cout << string(4, 'c') << endl;
cout << string{ 4, 'c' } << endl;
输出是:
cccc
c //a square '' before 'c'
答案 0 :(得分:5)
否则,
T
的构造函数分为两个阶段:
检查以
std::initializer_list
为唯一参数的所有构造函数,或者如果其余参数具有默认值,则作为第一个参数,并针对类型为{{1的单个参数的重载决策进行匹配}}如果前一阶段没有产生匹配,则
std::initializer_list
的所有构造函数都参与对由 braced-init-list 元素组成的参数集进行重载解析。 em>,限制条件是只允许非缩小转换。如果此阶段产生显式构造函数作为复制列表初始化的最佳匹配,则编译失败(注意,在简单的复制初始化中,不考虑显式构造函数全部)。
在你的情况下
T
使用以下构造函数。
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() );
中定义第二个构造函数,那么这两个构造函数都会产生相同的对象。
答案 1 :(得分:4)
两者都是constructor次调用,但它们调用两个不同的构造函数。第一个电话(&#34; 2&#34;在链接中)构建了一个字符计数,因此你得到了4&#39; c。
第二个构造函数(&#34; 9&#34;在链接中)采用std::initializer_list
。使用大括号而不是parens构造时,如果该类有一个构造函数采用initializer_list,它将始终优先。
如果有任何安慰,这种行为多年来困扰了程序员很多 ...