Ответ 1
Дополнение будет выполнять обычные арифметические преобразования в своих операндах, которые в этом случае приведут к тому, что операнды будут продвинуты до int из-за целые рекламные акции, и результатом будет также int.
Вы можете использовать uint16_t вместо auto, чтобы принудительно выполнить преобразование, или в общем случае вы можете использовать static_cast
.
Для обоснования того, почему тип, меньший, чем int, продвигается к более крупным типам, см. Почему короткое преобразование в int перед арифметическими операциями в C и С++?.
Для справки, из проекта стандартного раздела С++ 5.7
Аддитивные операторы:
[...] Обычные арифметические преобразования выполняются для операндов арифметический или перечисляемый тип [...]
и из раздела 5
Выражения:
[...] В противном случае интегральные акции (4.5) должны выполняться на оба операнда. 59 Затем применяются следующие правила: к продвинутым операндам [...]
и из раздела 4.5
Интегральные рекламные акции (внимание мое):
Значение целочисленного типа, отличного от bool, char16_t, char32_t или wchar_t , чей целочисленный ранг преобразования (4.13) меньше ранга int может быть преобразован в prvalue типа int, если int может представлять все значения типа источника; в противном случае исходное значение может преобразуется в prvalue типа unsigned int.
Предполагая, что int больше 16-бит.