Операнды в вашем выражении сложения подвергаются интегральному продвижению .
В частности, арифметические c операторы не принимают типы, меньшие чем int, в качестве аргументов и интегральные продвижения автоматически применяются после преобразования lvalue в rvalue, если применимо. Это преобразование всегда сохраняет значение.
Ваши a
и b
повышаются до int
или unsigned int
, добавляются, а затем преобразуются обратно в unsigned char
.
Если преобразование является ожидаемым поведением программы (с вашей точки зрения, как дизайнера), вы можете явно привести его к желаемому типу. Явное приведение не является сужающим преобразованием. Неявное приведение есть. Поэтому, если мы изменим неявное приведение на явное приведение, программа больше не будет неправильно сформирована.
T t = { static_cast<unsigned char>(a + b) };