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

rsy*_*640 -2 c++ constructor initializer-list

当我在下面编写一些代码时,我感到很奇怪.我期待相同的输出,但结果证明是错误的.为什么2个语句具有不同的输出,(expression-list)和{initializer-list}之间有什么区别?

cout << string(4, 'c') << endl;  
cout << string{ 4, 'c' } << endl; 
Run Code Online (Sandbox Code Playgroud)

输出是:

cccc  
c   //a square '' before 'c'
Run Code Online (Sandbox Code Playgroud)

R S*_*ahu 5

来自cppreference.com:

否则,将分T两个阶段考虑构造函数:

  • std::initializer_list作为唯一参数的所有构造函数,或者如果其余参数具有默认值,则作为第一个参数,将检查所有构造函数,并通过重载解析与单个参数类型进行匹配std::initializer_list

  • 如果前一阶段没有产生匹配,则所有构造函数都T参与对由包含braced-init-list元素组成的参数集的重载解析,并限制只允许非缩小转换.如果此阶段产生显式构造函数作为复制列表初始化的最佳匹配,则编译失败(注意,在简单的复制初始化中,根本不考虑显式构造函数).

在你的情况下

string(4, 'c')
Run Code Online (Sandbox Code Playgroud)

使用以下构造函数.

std::string(size_type count, 
            char ch, 
            const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

另一方面,

string{ 4, 'c' }
Run Code Online (Sandbox Code Playgroud)

使用以下构造函数.

std::string(std::initializer_list<char> ilist, 
            const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

如果没有定义第二个构造函数std::string,那么这两个构造函数都会产生相同的对象.