c – 哪些贪心的初始化器列表示例潜藏在标准库中?

由于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'
}

我找不到这个网站上的第三个例子,这个事情在休息室里出现了< C>聊天(与@rightfold,@Abyx和@JerryCoffin讨论),有点令人惊讶的是,转换std :: string构造函数使用{}而不是()来计算和使用字符,将其含义从n个第n个字符的字符(通常来自ASCII表),后跟另一个字符.

这不是通常的大括号禁止缩小转换,因为65是一个常量表达式,可以表示为char,并将转换回int(§8.5.4/ 7,子弹4)时保留其原始值(谢谢)到@JerryCoffin).

问题:在标准库中有更多的例子,它将一个()风格的构造函数转换为{} style,被一个初始化器列表构造函数贪婪匹配?

解决方法

我假设你的例子为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>作为参数,但我不认为任何这些都有一个重载的构造函数,当使用括号而不是大括号时将使用它.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...