为什么这个代码将字符串初始化为单个字符调用initializer_list构造函数?

tem*_*def 6 c++ string constructor initializer-list c++11

我最近正在研究一个C++项目,遇到了一个我无法完全理解的字符串构造函数的边缘情况.相关代码(您可以在此处运行)如下:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string directParens(1, '*');
    string directBraces{1, '*'};
    string indirectBraces = {1, '*'};

    cout << directParens.size() << endl;   // 1
    cout << directBraces.size() << endl;   // 2
    cout << indirectBraces.size() << endl; // 2
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

字符串的大括号初始化版本最终有两个字符,即char数字值1后跟星号.

我不明白为什么字符串的大括号初始化版本会调用initializer_list构造函数而不是构造函数来获取大小和字符.该initializer_list构造有这样的签名:

basic_string(std::initializer_list<CharT> init, 
             const Allocator& alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)

鉴于它stringbasic_stringchar 的别名,具体签名将是

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

初始化程序如何{1, '*'}包含类型int和类型的元素char,与此构造函数匹配?我的印象是,所有文字std::initializer_list必须具有相同的类型 - 是不正确的?

Nic*_*las 15

初始值设定项{1,'*'}如何与包含int和char类型的元素匹配此构造函数?

因为字面值1和字符'*'都可以转换为char不使用缩小转换.因此,他们有资格调用initializer_list<char>构造函数.使用列表初始化时,initializer_list构造函数始终具有优先级.如果可以initializer_list从参数调用构造函数,那么它将.

除非您希望列表中的元素是容器的元素,否则永远不要将braced-init-lists与容器一起使用.如果您打算将它们作为构造函数参数,那么请使用构造函数.

  • 过载分辨率并不关心转换是否正在缩小.它仍然会选择`initializer_list`构造函数,然后导致一个格式错误的程序. (5认同)