怪型推演
Strange type deduction
今天看到一个很奇怪的类型推导。这是代码:
unsigned int y = 15;
int k = 5;
auto t = k - y / 2;
因为 k
是 int
,我假设 t
的类型也应该是 int
。但令我惊讶的是,它的类型是unsigned int
。我找不到为什么类型被推断为 unsigned int
。知道为什么吗?
由于通常的算术转换,如果两个操作数具有相同的转换等级并且其中一个操作数具有无符号整数类型,则表达式的类型具有相同的无符号整数类型。
来自 C++ 17 标准(5 个表达式,第 10 页)
— Otherwise, if the operand that has unsigned integer type has rank
greater than or equal to the rank of the type of the other operand,
the operand with signed integer type shall be converted to the type of
the operand with unsigned integer type.
注意类型unsigned int
的转换等级等于类型int
的等级(signed int
)。来自 C++ 17 标准(4.13 整数转换等级,p.#1)
— The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type
下面是一个更有趣的例子。假设有两个声明
unsigned int x = 0;
long y = 0;
并且两种类型的宽度相同并且等于 4
字节。众所周知,long
类型的秩大于 unsigned int
类型的秩。出现一个问题,什么是表达式的类型
x + y
表达式的类型是unsigned long
.:)
这是一个演示程序,但使用的是 long long
和 unsigned long
.
类型,而不是 long
和 unsigned int
类型
#include <iostream>
#include <iomanip>
#include <type_traits>
int main()
{
unsigned long int x = 0;
long long int y = 0;
std::cout << "sizeof( unsigned long ) = "
<< sizeof( unsigned long )
<< '\n';
std::cout << "sizeof( long long ) = "
<< sizeof( long long )
<< '\n';
std::cout << std::boolalpha
<< std::is_same<unsigned long long, decltype( x + y )>::value
<< '\n';
return 0;
}
程序输出为
sizeof( unsigned long ) = 8
sizeof( long long ) = 8
true
即表达式 x + y
的类型是 unsigned long long
尽管表达式的操作数都不是这种类型。
今天看到一个很奇怪的类型推导。这是代码:
unsigned int y = 15;
int k = 5;
auto t = k - y / 2;
因为 k
是 int
,我假设 t
的类型也应该是 int
。但令我惊讶的是,它的类型是unsigned int
。我找不到为什么类型被推断为 unsigned int
。知道为什么吗?
由于通常的算术转换,如果两个操作数具有相同的转换等级并且其中一个操作数具有无符号整数类型,则表达式的类型具有相同的无符号整数类型。
来自 C++ 17 标准(5 个表达式,第 10 页)
— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
注意类型unsigned int
的转换等级等于类型int
的等级(signed int
)。来自 C++ 17 标准(4.13 整数转换等级,p.#1)
— The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type
下面是一个更有趣的例子。假设有两个声明
unsigned int x = 0;
long y = 0;
并且两种类型的宽度相同并且等于 4
字节。众所周知,long
类型的秩大于 unsigned int
类型的秩。出现一个问题,什么是表达式的类型
x + y
表达式的类型是unsigned long
.:)
这是一个演示程序,但使用的是 long long
和 unsigned long
.
long
和 unsigned int
类型
#include <iostream>
#include <iomanip>
#include <type_traits>
int main()
{
unsigned long int x = 0;
long long int y = 0;
std::cout << "sizeof( unsigned long ) = "
<< sizeof( unsigned long )
<< '\n';
std::cout << "sizeof( long long ) = "
<< sizeof( long long )
<< '\n';
std::cout << std::boolalpha
<< std::is_same<unsigned long long, decltype( x + y )>::value
<< '\n';
return 0;
}
程序输出为
sizeof( unsigned long ) = 8
sizeof( long long ) = 8
true
即表达式 x + y
的类型是 unsigned long long
尽管表达式的操作数都不是这种类型。