当在列表初始化中使用三元操作符时,是什么导致了int到unsigned int的隐式转换(以及long long的类似转换),而不是short到unsigned short的隐式转换(对于char也是如此)。
具体来说,我感到惊讶的是,i32v2函数编译得很好,而其他函数却不编译:
unsigned short f16(unsigned short x);
unsigned int f32(unsigned int x);
void i16(short value) {
unsigned short encoded{value}; // narrowing, makes sense
}
void i32(int value) {
unsigned int encoded{value}; // narrowing, makes sense
}
void i16v2(short value) {
unsigned short encoded{false ? value : f16(value)}; // narrowing, makes sense
}
void i32v2(int value) {
unsigned int encoded{false ? value : f32(value)}; // not narrowing, huh?
}这里的完整示例:https://godbolt.org/z/fVTcrr
我猜三元操作符隐式地将int转换为unsigned int,但我不明白为什么它不能类似地将short转换为unsigned short。
我希望,如果int是可能的,那么三元操作符也应该能够在可能的情况下将任何其他signed类型转换为unsigned:
如果目标类型是无符号的,则结果值是最小的无符号值,等于源值模2n,其中n是用来表示目标类型的位数。
(转换)
有人能解释一下这种行为吗?如果可能的话,可以参考标准或适用的Can页面吗?
发布于 2020-02-12 14:03:48
注意,对于false ? value : f16(value),首先在操作数上执行推广。对于算术算子,
如果传递给算术运算符的操作数是整数或非作用域枚举类型,则在任何其他操作之前(但在lvalue-rvalue转换(如果适用的话)之后),操作数将经历积分提升。
和
以下隐式转换被归类为整体晋升:
signed char或signed short可转换为int;这意味着false ? value : f16(value)的返回类型是int,然后导致向unsigned short的收缩转换。
另一方面,返回类型,即false ? value : f32(value)的公共类型是unsigned int,然后是unsigned int encoded{false ? value : f32(value)};。
否则,操作数具有整数类型(因为此时提升了
bool、char、char8_t、char16_t、char32_t、wchar_t和非作用域枚举),并应用积分转换来生成公共类型,如下所示:
对于long或long long,他们不会被提升到int,这样他们就不会有这样的问题了。
https://stackoverflow.com/questions/60189901
复制相似问题