考虑以下程序:
struct uint1 {
unsigned x;
uint1(unsigned x_) : x(x_) { }
};
struct foo { uint1 a; };
foo f(int v) {
return {v};
}
struct bar { unsigned a; };
bar g(int v) {
return {v};
}
现在,我们在哪里可以缩小转换范围?
编译器 | 版本缩小 | 缩小CCD_ 2中的转换 |
---|---|---|
GCC | ||
clang | 13.0 | 否 | 是[/tr>
MSVC |
GCC和Clang似乎没有将其归类为缩小转换是正确的。
所讨论的初始化是foo
对象的初始化。其构造函数参数包含在{}
中。由于构造函数的参数不是数字类型,因此此初始化中不能有缩小转换。它是struct uint1
。
那么struct uint1
锥从哪里来呢?它是从v
转换而来的,但不是通过支撑初始化的方式。v
周围的一对大括号已经被uint1
的构造函数占用。
这相当于foo{uint1(v)}
。
另一方面,MSVC似乎将其解释为foo(uint1{v})
,我认为这种解释是不合理的。
两个编译器都没有抱怨显式的foo{uint1(v)}
,这是标准所要求的,因为在顶层没有变窄。