Проблема в том, что int
, long
, long long
и их неподписанные версии всегда имеют разные типы, даже если они имеют одинаковое количество битов. Например. is_same_v<int, long>
всегда false
.
Зная это, DWORD
определяется как unsigned long
в 64-битной Windows, а uint32_t
и uint64_t
определяются как unsigned int
и unsigned long long
соответственно. Таким образом, среди ваших перегрузок нет идеального соответствия для DWORD
. Но, поскольку unsigned long
a.k.a DWORD
можно неявно преобразовать во все эти типы, вы получите неоднозначный вызов.
Примечание: на платформе, где long
и unsigned long
являются 64-битными типами, вы получите ту же неоднозначность, только с long long
и unsigned long long
соответственно.
Чтобы решить вашу проблему, вам нужно добавить недостающие перегрузки long
и unsigned long
, чтобы действительно охватить все интегральные типы, чтобы обеспечить идеальное соответствие для всех из них.
Возможно, вы захотите переписать сигнатуры вашей функции с псевдонимов (u)intXX_t
до int
, long
, long long
и их неподписанных вариантов, чтобы сделать более очевидным, что все покрыто. Вы также можете захотеть перегрузку для short
и unsigned short
.