使用Microsoft C ++ 2017 64位版本,以下代码行生成编译错误,并且对重载函数的调用不明确:
print(pmc.PageFaultCount);
我定义了以下打印函数,以期明确涵盖所有常用的整数类型:
void print(int32_t n);
void print(int64_t n);
void print(uint32_t n);
void print(uint64_t n);
pmc.PageFaultCount
声明为DWORD
,该文档记录为无符号32位整数。我希望选择uint32_t
重载。
这是如何模棱两可的?
更重要的是,如果以上一组重载不足以打印任何整数,那么什么组重载就足够了?
答案 0 :(得分:4)
DWORD
是unsigned long
的别名,而uint32_t
是unsigned int
的别名。因此,您还需要另一组包含long
和unsigned long
的重载(可能还有unsigned long long
long long
,unsigned short
,short
,{{1 }},unsigned char
,常规signed char
,char
,wchar_t
,char16_t
,char32_t
和枚举类型)。
答案 1 :(得分:0)
问题是int
,long
,long long
及其无符号版本始终是不同的类型,即使它们具有相同的位数。例如。 is_same_v<int, long>
始终为false
。
知道了这一点,DWORD
在64位Windows上恰好被定义为unsigned long
,而uint32_t
和uint64_t
被定义为unsigned int
和{{1} } 分别。因此,您的重载中没有unsigned long long
的完美匹配。但是,由于DWORD
也可以unsigned long
隐式转换为所有这些类型,因此您会得到一个模棱两可的调用。
注意:在DWORD
和long
是64位类型的平台上,您将获得相同的歧义,仅分别使用unsigned long
和long long
。
要解决您的问题,您需要添加缺失的unsigned long long
和long
重载以真正覆盖所有整数类型,以便使它们完美匹配。
您可能希望将函数签名从unsigned long
别名重写为(u)intXX_t
,int
,long
及其未签名的变体,以使所有内容都变得显而易见。覆盖。您可能还需要long long
和short
的重载。