Проверка на переполнение действительно выполняется путем сравнения исходного значения с минимальными / максимальными значениями целевого типа (std::uint32_t
). Но это еще не все - как вы собираетесь обрабатывать ситуацию, в которой исходное значение находится за пределами области целевого значения? В вашем случае отрицательный val
уже поднимает этот вопрос, и это не затрагивает сценарий переполнения, поскольку отрицательные значения, назначенные целым типам без знака, хорошо определены (хотя полученное значение может не соответствовать ожидаемому).
Вот простое решение, характерное для long int
до std::uint32_t
:
#include <limits>
std::uint32_t new_val = val < 0 || val > std::numeric_limits<std::uint32_t>::max() ?
0 : static_cast<std::uint32_t>(val);
Это безопасно и не должно выдавать предупреждения компилятора (-Wconversion
), так как приведение является явным. Проблема заключается в том, что результирующее значение 0
представляет два состояния - неудачное преобразование, а также успешное преобразование, когда исходное значение val
равно нулю. Чтобы смягчить это, C ++ 17 дает вам, например, std::optional
. Перед этим вам потребуется дополнительная отправка по делу val == 0
.