如果第二个属性未进行括号初始化,则使用支撑初始化程序编译缩小转换

时间:2016-06-20 18:00:21

标签: c++ c++11

从c ++ 11开始,list initialization(包括aggregate initialization)不允许缩小转化率。所以基本上:

char c{1000}; // Does not compile with g++, clang, vc

可是:

std::pair<char, double> p{1000, 1.0};

与所有编译器一起编译?

可是:

std::pair<char, double> p{1000, {1.0}};

不用VC编译(错误C2398),用clang发出警告并用g ++静默编译......

我原本期望VC的行为到处都是,即一个非允许的缩小转换会引发错误。哪个编译器是对的?

另一方面,以下代码段中的变量声明都没有编译:

struct X {
    char c;
    double d;
};

X x1{999, 1.0};
X x2{999, {1.0}};

struct Y {
    char c;
    double d;
    Y (char c, double d) : c(c), d(d) { }
};

Y y1{999, 1.0};
Y y2{999, {1.0}};

所以我的一个猜测可能是std::pair有什么特别之处?还有什么能缩小支撑初始化的范围?

1 个答案:

答案 0 :(得分:14)

  1. std::pair<char, double> p{1000, 1.0};未被诊断,因为它调用了template<class U1, class U2> pair(U1&&, U2&&)构造函数(U1 == intU2 == double),这是完全匹配的;在你进入构造函数体之前,缩小并不会发生。

  2. std::pair<char, double> p{1000, {1.0}};无法调用该构造函数,因为 braced-init-list {1.0}是非推断的上下文,因此您无法推断U2