自 C++11 起,标准库容器并std::string
具有采用初始化列表的构造函数。此构造函数优先于其他构造函数(甚至,正如@JohannesSchaub-litb 在评论中指出的那样,甚至忽略其他“最佳匹配”标准)。()
在将所有带括号形式的构造函数转换为其大括号版本时,这会导致一些众所周知的缺陷{}
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
void print(std::vector<int> const& v)
{
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, ","));
std::cout << "\n";
}
void print(std::string const& s)
{
std::cout << s << "\n";
}
int main()
{
// well-known
print(std::vector<int>{ 11, 22 }); // 11, 22, not 11 copies of 22
print(std::vector<int>{ 11 }); // 11, not 11 copies of 0
// more surprising
print(std::string{ 65, 'C' }); // AC, not 65 copies of 'C'
}
我在这个网站上找不到第三个例子,这件事出现在 Lounge<C++> 聊天中(与@rightfold、@Abyx 和@JerryCoffin 讨论),有点令人惊讶的是转换std::string
构造函数需要计数和一个要使用的字符{}
而不是()
,将其含义从n
该字符的副本更改为n
第 - 个字符(通常来自 ASCII 表),然后是另一个字符。
这没有被缩小转换的通常大括号禁止所捕获,因为 65 是一个常量表达式,可以表示为 char 并且在转换回 int 时将保留其原始值(第 8.5.4/7 节,第 4 条)(谢谢给@JerryCoffin)。
问题:标准库中是否还有更多示例,其中将()
样式构造函数转换为{}
样式,由初始化列表构造函数贪婪匹配?