从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'
}
我在这个网站上找不到第三个例子,而这个问题出现在休息室&lt; C ++&gt;聊天(与@rightfold,@ Abyx和@JerryCoffin讨论),有点令人惊讶的是,将std::string
构造函数转换为计数和字符使用{}
而不是()
,将其含义从n
个字符副本更改为n
个字符(通常来自ASCII表),后跟另一个字符。
这通常不会限制缩小转换,因为65是一个常量表达式,可以表示为char,并在转换回int时保留其原始值(§8.5.4/ 7,bullet 4) )(感谢@JerryCoffin)。
问题:标准库中是否有更多示例将()
样式构造函数转换为{}
样式,并且初始化列表构造函数会贪婪地匹配?< / p>
答案 0 :(得分:4)
我假设您的std::vector<int>
和std::string
示例也涵盖了其他容器,例如std::list<int>
,std::deque<int>
等具有相同容器的容器问题显然是std::vector<int>
。同样,int
不是唯一的类型,因为它也适用于char
,short
,long
及其unsigned
版本(可能还有其他几个整体)类型,也是。)
我认为还有std::valarray<T>
,但我不确定T
是否允许为整数类型。实际上,我认为它们有不同的语义:
std::valarray<double>(0.0, 3);
std::valarray<double>{0.0, 3};
还有一些其他标准C ++类模板以std::initializer_list<T>
作为参数,但我不认为其中任何一个都有重载的构造函数,在使用括号而不是大括号时会使用它。
答案 1 :(得分:3)
只是搜索initializer_list
。
所有序列,它们都具有类似于vector的构造函数:
的valarray
basic_string的
无序集合,有一个构造函数,它接受一个整数来确定初始存储桶数。
我认为这就是全部。
#include <unordered_set>
#include <iostream>
int main() {
std::unordered_set<int> f (3);
std::unordered_set<int> g {3};
std::cout << f.size() << "/" << g.size() << std::endl; // prints 0/1.
}