简体   繁体   English

C ++对带有unsigned int的重载函数的模糊调用

[英]C++ ambiguous call to overloaded function with unsigned int

This seems inconsistent. 这似乎不一致。 I have 3 functions f overloaded for signed types short , int and long long . 我有3个功能f重载符号类型shortintlong long If you pass an unsigned short then it gets promoted to the next biggest signed type int . 如果你传递一个unsigned short那么它会被提升为下一个最大的signed类型int However if you pass unsigned int then it doesn't get promoted to signed long long which is what I would expect, rather compiler complains about ambiguous call to overloaded function. 但是,如果你传递unsigned int那么它不会被提升为signed 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) 
}

It is inconsistent, yes, but it is The Way The Language Is, and you have to cope, eg if you want f((unsigned int)0) to call the long long overload, then provide a wrapper, 不一致的,是的,但它是The Way The Language Is,你必须应对,例如,如果你想要f((unsigned int)0)来调用long long overload,那么提供一个包装器,

inline void f(unsigned int x) { f((long long)x); }

The designers of C++ would have ideally liked to make both of your cases fail overload resolution. C ++的设计者理想地喜欢让你的两种情况都失败了重载决议。 But there was this legacy thing (dating all the way back to "K&R" C), called "default argument promotion", that, essentially, says the compiler will implicitly convert all integer types narrower than int to int if necessary to match a function signature, and all floating point types narrower than double to double ditto. 但是有这个传统的东西(一直回到“K&R”C),称为“默认参数提升”,基本上说,如果需要匹配函数,编译器将隐式地将所有比int更窄的整数类型转换为int签名,所有浮点类型都比doubledouble都要窄。

So it's the f((unsigned short)0) case that is the odd man out, really. 所以这是f((unsigned short)0)情况,真是奇怪的人。

http://en.cppreference.com/w/cpp/language/implicit_conversion http://en.cppreference.com/w/cpp/language/implicit_conversion

Integral promotion does not get you from unsigned int to long long . 积分促销不会让你unsigned int ,以long long

Integral promotion does get you from unsigned short to int . 整体推广确实可以让你从unsigned shortint

Integral conversion from unsigned int is considered equally good for your overloads. 来自unsigned int积分转换被认为同样适用于您的重载。

Promotion ends at int and/or unsigned int unless your source type is an enum that requires a larger integral type to fit it. 促销以int和/或unsigned int 结尾 ,除非您的源类型是enum ,需要更大的整数类型才能适合它。

Promotion is preferred to conversion, so your first case is unambiguous. 促销比转换更受欢迎,因此您的第一个案例是明确的。 In the second case, there is no promotion path, so your code is ambiguous. 在第二种情况下,没有升级路径,因此您的代码含糊不清。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM