C++ 为什么我不能用统一初始化初始化字符串?

C++ 为什么我不能用统一初始化初始化字符串?,c++,c++11,initializer-list,stdstring,C++,C++11,Initializer List,Stdstring,我有一个模拟窗口的程序;因此,我将窗口的内容存储在一个成员数据内容中,该内容是std::string类型: 正如您在上面所看到的,我无法使用大括号初始化器列表初始化成员内容,编译器抱怨该列表缩小了类型。但它与直接初始化一起工作 为什么我不能在构造函数初始值设定项列表中使用上面的花括号初始化列表来调用std::stringsize\u t count,char 为什么是std::string str{5u,'*'};//编译但不正常工作但给出的结果不正确 我最关心的是,为什么相同的初始化在构造函数

我有一个模拟窗口的程序;因此,我将窗口的内容存储在一个成员数据内容中,该内容是std::string类型:

正如您在上面所看到的,我无法使用大括号初始化器列表初始化成员内容,编译器抱怨该列表缩小了类型。但它与直接初始化一起工作

为什么我不能在构造函数初始值设定项列表中使用上面的花括号初始化列表来调用std::stringsize\u t count,char

为什么是std::string str{5u,'*'};//编译但不正常工作但给出的结果不正确

我最关心的是,为什么相同的初始化在构造函数成员初始化列表上不起作用,但在main中起作用却没有预期的结果

首先,由于std::string的构造函数sts::stringsize\u t count,char是显式的,因此不能隐式调用它

其次,您不是在调用内容{width*height,fill}中的std::stringsize\u t,char,而是在调用std::stringstd::initializer\u list。因此,表达式width*height生成一个无符号int,然后隐式转换为相关类型的char,例如,您传递了windowmain{15,25,'*'};这将产生char15*25=char375,这是未定义的行为,因为该值溢出了有符号字符。你可以上你的机器♣ 或其他值作为初始值设定项列表中的第一个元素,但它是未定义的行为,并且作为初始值设定项列表中的第二个元素。因此,您将传递std::initializer_list{'♣', }.

只要调用具有多个参数的显式构造函数,就可以使用直接初始化。 第二个问题的答案是:我最关心的是,为什么同一个初始化在构造函数成员初始化列表上不起作用,但在main中起作用却没有预期的结果

实际上它与构造函数成员初始化列表不存在任何关系,但实际上考虑如下:

    char c{ 127 }; // the maximum integer positive value that a signed char can hold so no narrowing conversion here. So it is OK.

    char c2{ 128 }; // Now 128 overflows the variavle c2. c2 is of type char and as you know it can hold positive values in range 0 to 127 and negative -1 to -128
    unsigned char uc{ 255 }; // ok because an unsigned char can hold 255
    unsigned char uc2{ 300 }; // error as the error above. An unsigned char can hold 255 as max positive value.

    unsigned char uc3 = 321; // ok // ok but you may get a warning. a Copy-initialization is not safe.
    cout << uc3 << endl; // you may get `A`. 321 % 256 = 65. 65 % 256 = 65. 65 in ASCII in some implementations it represents the character "A".

最后的弹头应该是72点字体。我看到很多C++程序员迷恋于我自己的统一初始化,并且滥用/滥用它,而不是我……我已经学到了教训。
    char c{ 127 }; // the maximum integer positive value that a signed char can hold so no narrowing conversion here. So it is OK.

    char c2{ 128 }; // Now 128 overflows the variavle c2. c2 is of type char and as you know it can hold positive values in range 0 to 127 and negative -1 to -128
    unsigned char uc{ 255 }; // ok because an unsigned char can hold 255
    unsigned char uc2{ 300 }; // error as the error above. An unsigned char can hold 255 as max positive value.

    unsigned char uc3 = 321; // ok // ok but you may get a warning. a Copy-initialization is not safe.
    cout << uc3 << endl; // you may get `A`. 321 % 256 = 65. 65 % 256 = 65. 65 in ASCII in some implementations it represents the character "A".
char c3 = 321; // signed char overflows
cout << c3 << endl; // you may get "A" and think it is correct.
constexpr int i = 10;
constexpr int j = 5;
std::string str{ i * j, 'f' }; // ok as long as the values are constexpr and don't cause any narrowing conversion this value: 10 * 5 = 50 which is a well defined signed-char value.

int i = 10;
int j = 5;
std::string str{ i * j, 'f' }; // error. the values of i and j are not constant thus it may overflow a signed char causing narrowing conversion thus the compiler is wise enough to prevent this initialization.