这似乎不一致。我为签名类型f
,short
和int
重置了3个函数long long
。如果您传递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)
}
答案 0 :(得分:6)
它 不一致,是的,但它是The Way The Language Is,你必须应对,例如如果您希望f((unsigned int)0)
调用long long
重载,请提供包装器
inline void f(unsigned int x) { f((long long)x); }
C ++的设计者理想地喜欢让你的两种情况失败重载解析。但是有一些传统的东西(一直追溯到“K& R”C),称为“默认参数提升”,基本上说,编译器会隐式地将所有比int
窄的整数类型转换为{ {1}}如果需要匹配函数签名,并且所有浮点类型都比int
更窄到double
同上。
所以这是double
案例,真是奇怪的人。
答案 1 :(得分:4)
http://en.cppreference.com/w/cpp/language/implicit_conversion
整体推广会不让您从unsigned int
转到long long
。
整体推广确实让您从unsigned short
转到int
。
来自unsigned int
的积分转换被视为同样适合您的重载。
促销在int
和/或unsigned int
结束,除非您的源类型是enum
,需要更大的整数类型才能适合它。
促销比转换更受欢迎,因此您的第一个案例是明确的。在第二种情况下,没有升级路径,因此您的代码不明确。