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

时间:2016-10-26 18:33:00

标签: c++ integer-promotion

这似乎不一致。我为签名类型fshortint重置了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) 
}

2 个答案:

答案 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,需要更大的整数类型才能适合它。

促销比转换更受欢迎,因此您的第一个案例是明确的。在第二种情况下,没有升级路径,因此您的代码不明确。