为什么初始化列表与表达式列表相比有不同的结果

Why does initializer-list have different result compared with expression-list

下面写代码的时候感觉很奇怪。我期待同样的输出,但事实证明是错误的。为什么这 2 个语句有不同的输出,(expression-list) 和 {initializer-list} 之间有什么区别?

cout << string(4, 'c') << endl;  
cout << string{ 4, 'c' } << endl; 

输出是:

cccc  
c   //a square '' before 'c'

两者都是constructor调用,但它们调用了两个不同的构造函数。第一次调用(link 中的“2”)构造了一个字符数,因此在你的情况下你得到 4 个“c”。

第二个构造函数(link 中的“9”)采用 std::initializer_list。当您使用大括号而不是括号构造时,if class 有一个采用 initializer_list 的构造函数,它将始终优先。

如果有什么安慰的话,这种行为多年来一直困扰着很多程序员...

来自cppreference.com

Otherwise, the constructors of T are considered, in two phases:

  • All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list

  • If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).

你的情况

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 中没有定义第二个构造函数,那么这两个构造函数将生成相同的对象。