3. 参数匹配
#include <iostream>
void f(int) { std::cout << 1; }
void f(unsigned) { std::cout << 2; }
int main() {
f(-2.5);
}
答案是:CE
在选择重载函数时,如果没有完全匹配的,就会通过转换选择一个次匹配的,转换的种类如表中所示,题中所给的转换是属于浮点到整形的转换。相比之下没有更好的,所以编译器不知道选择哪个重载函数,所以是ill-formed。
This overload is ambiguous. Why?
There are two viable functions for the call f(-2.5)
. For the compiler to select one, one of them needs to be better than the other, or the program is ill-formed. In our case, they are equally good, making the program ill-formed.
According to §13.3.3 in the standard, a viable one-argument function is better than another if the conversion sequence for the argument is better. So why isn’t the int conversion sequence better than the unsigned conversion sequence, given that the double is signed?
All conversions are given a rank, and both “double => int” and “double => unsigned int” are of type “floating-integral conversion”, which has rank “conversion”. See Table 12 in the standard and §4.9. Since they have the same rank, no conversion is better than the other, and the program is ill-formed.
接上期,题中一共列出了4种函数声明和两种参数形式,列表如下:
函数声明&参数类型 | const char [] | const char * |
---|---|---|
const std::string & | Conversion | Conversion |
const void * | Array to pointer | Pointer Conversion |
template T &s | T=const char &[] | T=const char * & |
templateconst char (&)[N] | Identity | 不匹配 |
可见,对于T&来说,对两种参数都是属于Exact Match,而偏特化版本对const char[] 是Identity,而对const char * 不匹配,结果一目了然,而const void * 和 const std::string & 都需要进行转换,所以,const char [] 匹配 const char (&)[N],const char * 匹配T&.