Из-за обычных арифметических преобразований c, если два операнда имеют одинаковый ранг преобразования, а один из операндов имеет тип целого без знака, тогда тип выражения имеет тот же тип целого числа без знака.
Из Стандарт C ++ 17 (5 выражений, стр. # 10)
- В противном случае, если операнд с целочисленным типом без знака имеет ранг, больший или равный рангу типа другого операнда, операнд с целым типом со знаком должен быть преобразован в тип операнда с целым типом без знака.
Обратите внимание, что ранг преобразования типа unsigned int
равен рангу типа int
(signed int
). Из стандарта C ++ 17 (4.13. Целочисленный ранг преобразования, стр. # 1)
- ранг любого целого типа без знака должен равняться рангу соответствующего целочисленного типа со знаком
Более интересным примером является следующее. Предположим, что есть два объявления
unsigned int x = 0;
long y = 0;
, а ширина обоих типов одинакова и равна, например, 4
байтов. Как известно, ранг типа long
больше, чем ранг типа unsigned int
. Возникает вопрос, какой идентификатор типа выражения
x + y
Тип выражения unsigned long
.:)
Вот демонстрационная программа, но вместо типов long
и unsigned int
используются типы long long
и unsigned long
.
#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
хотя ни один из операндов выражения не имеет этот тип.