C++ 使用统一初始化时未调用std::string(count,ch)

C++ 使用统一初始化时未调用std::string(count,ch),c++,string,c++11,uniform-initialization,C++,String,C++11,Uniform Initialization,我刚刚被一个看似无辜的尝试抓住了,它使用统一的初始化语法调用了一个大小和字符值: std::string s{ 10, '\0' }; 我认为这将创建一个长度为10的字符串,用\0初始化 尽管它实际上调用了构造函数,该构造函数接受一个初始值设定项列表,从而创建了一个长度为2的字符串,并用{'\n','\0'}初始化 看 在使用统一初始化时,有没有办法避免这种陷阱?还是我得小心点 注意:以前有人问过,但没有人回答如何避免这个陷阱。你只要小心就行了 一般来说,当人们告诉你“使用统一的初始化,以便所

我刚刚被一个看似无辜的尝试抓住了,它使用统一的初始化语法调用了一个大小和字符值:

std::string s{ 10, '\0' };
我认为这将创建一个长度为10的字符串,用
\0
初始化

尽管它实际上调用了构造函数,该构造函数接受一个初始值设定项列表,从而创建了一个长度为2的字符串,并用
{'\n','\0'}
初始化

在使用统一初始化时,有没有办法避免这种陷阱?还是我得小心点


注意:以前有人问过,但没有人回答如何避免这个陷阱。

你只要小心就行了

一般来说,当人们告诉你“使用统一的初始化,以便所有内容都是一致的,而且是统一的”时,忽略它们。我的意思是,一定要使用统一的初始化,但不要相信那个童话故事

此外,请忽略功能的名称


你只要小心就行了

一般来说,当人们告诉你“使用统一的初始化,以便所有内容都是一致的,而且是统一的”时,忽略它们。我的意思是,一定要使用统一的初始化,但不要相信那个童话故事

此外,请忽略功能的名称


这个特性在标准中并没有正式命名为“统一初始化”(或unicorn)。公平地说,列表初始化不必这样做。如果委员会没有犯两个错误的话,它本可以包含所有形式的初始化:偏爱
初始化器\u list
构造函数和禁止缩小转换范围。删除这两个选项,您就可以合法地用
{}
替换
()
初始化的任何情况。这个特性在标准中没有正式命名为“统一初始化”(或unicorn)。公平地说,列表初始化不必以这种方式工作。如果委员会没有犯两个错误的话,它本可以包含所有形式的初始化:偏爱
初始化器\u list
构造函数和禁止缩小转换范围。删除这两个选项,你就可以合法地用
{}
替换
()
初始化的任何情况。我认为维基百科上的条目很好地描述了这一点:“统一初始化不会替换构造函数语法,这有时仍然是需要的。如果一个类有一个初始化器列表构造函数(
TypeName(initializer\u list));
),则它优先于其他形式的构造,前提是初始值设定项列表符合序列构造函数的类型。“@clcto编译器似乎渴望使用初始值设定项列表构造函数,即使该列表包含不一致的类型()。平心而论,这里有一个编译器警告。@zett42:根据记录,这种行为是由
[over.match.list]/1
保证的;大体上构造函数分两个阶段进行查找,如果存在任何初始值设定项列表构造函数,那么不管是好是坏,都是这样。我认为上的wikipedia条目对此进行了很好的描述:“统一初始化不会取代构造函数语法,这在某些时候仍然是需要的。如果类具有初始值设定项列表构造函数(
TypeName(initializer_list);
),则它优先于其他形式的构造,前提是initializer列表符合序列构造函数的类型。“@clcto编译器似乎渴望使用initializer list构造函数,即使该列表包含不一致的类型()。为了公平起见,有一个编译器警告。@zett42:记录在案,这种行为是由
[over.match.list]/1
保证的;基本上,构造函数是分两个阶段查找的,如果存在任何初始值设定项列表构造函数,那么这就是你得到的结果,无论是好是坏。