这是字符串的构造:
string s {"Hello world!"};
字符串类具有以下可能绑定的构造函数:
来自char指针/数组:
string (const char* s);
来自initializer_list:
string (initializer_list<char> il);
起初我以为它会调用initializer_list
因为参数是支撑的。然后我看到initializer_list接受char
的参数,但那是一个字符串。
然后我意识到{""}
可以隐式转换为char[]
,因此它可能会调用第一个构造函数......在这种情况下,是一对括号自动添加到列表周围(例如{ {1}})?
那么它实际上调用了哪个构造函数?
这个怎么样:
({""})
它们是一样的吗?
假设字符串也有一个像double d1 (100);
double d2 {100};
这样的构造函数,那么它会调用哪一个?
答案 0 :(得分:8)
在C ++ 11中,花括号{}
用于统一初始化。可以使用花括号初始化任何可以初始化的对象。优先选择采用initializer_list<T>
的构造函数,因此如果花括号初始化可以匹配多个构造函数,并且其中一个构造函数需要initializer_list
,那么将会选择它。但是,如果没有initializer_list
构造函数匹配,则还会考虑其他构造函数。
例如:
vector<int> two_elems{5,10}; // A vector containing two elements
vector<int> five_elems(5,10); // A vector containing five elements
vector<int> five_elems_also{10,10,10,10,10}; // Equivalent to the above
在您的示例中,您使用string
初始化char const[13]
。如果initializer_list<char const*>
具有此类构造函数,则匹配string
,但它与initializer_list<char>
不匹配。所以参数与其他构造函数匹配,而char const*
的构造函数是最佳匹配。
请注意,由于含糊不清,最好不要使用大括号初始化来初始化容器(例如vector
,set
,list
,甚至string
),除非您打算使用initializer_list
构造函数。例如,没有办法调用使用大括号初始化vector<size_t>
的{{1}}构造函数,因为该参数列表也将匹配size_t, T
构造函数。另一个例子:
initializer_list
上面的两行调用非常不同的构造函数并不是很明显,如果在维护期间(或代码发生在模板中)的类型更改为另一行,程序员可能会对突然行为感到非常惊讶变化
答案 1 :(得分:5)
string(const char*)
{}
语法并不一定意味着std::initializer_list
。