我最近正在研究一个C项目,并遇到了一个我无法完全理解的字符串构造函数的边缘情况.相关代码(
you can run here)如下:
#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; }
字符串的大括号初始化版本最终有两个字符,即一个数字值为1,后跟一个星号的字符.
我不明白为什么字符串的大括号初始化版本调用initializer_list构造函数而不是构造函数接受大小和字符. initializer_list构造函数具有以下签名:
basic_string(std::initializer_list<CharT> init,const Allocator& alloc = Allocator());
鉴于string是basic_string char的别名,特定的签名将是
string(std::initializer_list<char> init,const Allocator& alloc = Allocator());
初始值设定项{1,’*’}如何与包含int和char类型的元素匹配此构造函数?我的印象是std :: initializer_list中的所有文字都必须具有相同的类型 – 这是不正确的?
解决方法
How is the initializer {1,‘*’},which contains elements both of type int and of type char,matching this constructor?
因为文字1和字符’*’都可以转换为char而不使用缩小转换.因此,他们有资格调用initializer_list< char>构造函数.并且initializer_list构造函数在使用列表初始化时始终具有优先级.如果可以从参数调用initializer_list构造函数,那么它将.
除非您希望列表中的元素是容器的元素,否则永远不要将braced-init-lists与容器一起使用.如果您打算将它们作为构造函数参数,那么请使用构造函数.