Почему бы вам не получить два дополнения, как это:
uint32_t num = 10;
uint32_t cmp = ~num + 1; // this is two's complement of 10.
Разве это не работает для вас?
РЕДАКТИРОВАТЬ: если вы беспокоитесь, что может произойти переполнение(для подписанного или неподписанного), просто сделайте это сначала:
if(~num == std::numeric_limits<MyIntType>::max()) {
// overflow mitigation
}
Вы также можете статически проверить, является ли ваш тип подписанным или неподписанным для смягчения проблем переполнения соответствующими способами с std::is_signed
и std::is_unsigned
.