C++ 对带有 unsigned int 的重载函数的模糊调用
C++ ambiguous call to overloaded function with unsigned int
这似乎不一致。我为有符号类型 short
、int
和 long long
重载了 3 个函数 f
。如果您传递一个 unsigned short
,那么它会被提升为下一个最大的有符号类型 int
。但是,如果你传递 unsigned int
那么它不会被提升为有符号 long long
这是我所期望的,而是编译器抱怨对重载函数的模棱两可的调用。
void f(short x) { std::printf("f(short)\n"); }
void f(int x) { std::printf("f(int)\n"); }
void f(long long x) { std::printf("f(long long)\n"); }
int main()
{
f((unsigned short)0); // Fine: calls f(int)
// f((unsigned int)0); // Ambiguous: could be f(short), f(int) or f(long long)
}
它是不一致,是的,但这是语言的方式,你必须应付,例如如果你想 f((unsigned int)0)
调用 long long
重载,那么提供一个包装器,
inline void f(unsigned int x) { f((long long)x); }
C++ 的设计者希望让您的两个案例都失败 重载解析。但是有一个遗留的东西(一直追溯到 "K&R" C),叫做 "default argument promotion",从本质上说,编译器会隐式地将所有窄于 int
的整数类型转换为 int
如果需要匹配函数签名,所有比 double
窄到 double
的浮点类型同上。
所以 f((unsigned short)0)
的情况确实很奇怪。
http://en.cppreference.com/w/cpp/language/implicit_conversion
积分促销 不会 让您从 unsigned int
提高到 long long
。
积分促销确实让您从unsigned short
升至int
。
unsigned int
的积分转换被认为同样适合您的重载。
促销 结束 在 int
and/or unsigned int
除非您的源类型是需要更大整数类型的 enum
适合它。
推广比转化更重要,所以你的第一个案例是明确的。第二种情况,没有提升路径,所以你的代码有歧义。
这似乎不一致。我为有符号类型 short
、int
和 long long
重载了 3 个函数 f
。如果您传递一个 unsigned short
,那么它会被提升为下一个最大的有符号类型 int
。但是,如果你传递 unsigned int
那么它不会被提升为有符号 long long
这是我所期望的,而是编译器抱怨对重载函数的模棱两可的调用。
void f(short x) { std::printf("f(short)\n"); }
void f(int x) { std::printf("f(int)\n"); }
void f(long long x) { std::printf("f(long long)\n"); }
int main()
{
f((unsigned short)0); // Fine: calls f(int)
// f((unsigned int)0); // Ambiguous: could be f(short), f(int) or f(long long)
}
它是不一致,是的,但这是语言的方式,你必须应付,例如如果你想 f((unsigned int)0)
调用 long long
重载,那么提供一个包装器,
inline void f(unsigned int x) { f((long long)x); }
C++ 的设计者希望让您的两个案例都失败 重载解析。但是有一个遗留的东西(一直追溯到 "K&R" C),叫做 "default argument promotion",从本质上说,编译器会隐式地将所有窄于 int
的整数类型转换为 int
如果需要匹配函数签名,所有比 double
窄到 double
的浮点类型同上。
所以 f((unsigned short)0)
的情况确实很奇怪。
http://en.cppreference.com/w/cpp/language/implicit_conversion
积分促销 不会 让您从 unsigned int
提高到 long long
。
积分促销确实让您从unsigned short
升至int
。
unsigned int
的积分转换被认为同样适合您的重载。
促销 结束 在 int
and/or unsigned int
除非您的源类型是需要更大整数类型的 enum
适合它。
推广比转化更重要,所以你的第一个案例是明确的。第二种情况,没有提升路径,所以你的代码有歧义。