为何同为64位的long与long long类型在重载解析中表现不同?
为什么long和long long在重载解析中表现不同?
使用Apple Clang(Xcode 14)针对x86_64架构编译以下代码时,第二个foo(j)调用会出现歧义错误,但第一个foo(i)调用正常,且static_assert验证long和long long的大小一致。
#include <iostream> #include <stdint.h> static void foo( long v ) { std::cout << v; } static void foo( unsigned long v ) { std::cout << v; } int main(int argc, const char * argv[]) { static_assert( sizeof(long) == sizeof(long long), "wrong size"); long i = 3; foo( i ); long long j = 3; foo( j ); return 0; }
编译报错:
error: call to 'foo' is ambiguous
原因分析
C++的重载解析规则只关注类型本身的身份,而非类型的内存大小。即使long和long long在当前平台下都是64位有符号整数,它们依然是两个完全独立的类型。
- 对于
foo(i):参数是long类型,直接匹配foo(long)重载,没有歧义。 - 对于
foo(j):参数是long long类型,编译器需要从两个重载中选择最佳匹配:- 匹配
foo(long):需要将long long隐式转换为long,属于标准转换序列中的「整数转换」。 - 匹配
foo(unsigned long):需要将long long隐式转换为unsigned long,同样属于标准转换序列中的「整数转换」。
- 匹配
这两种转换的优先级完全相同,编译器无法判定哪一个是更合适的选择,因此抛出歧义错误。
内容的提问来源于stack exchange,提问作者JWWalker
相关产品推荐
相关产品推荐

