我不得不花费一些时间来查找并修复我在以下代码中设法隔离的错误:
#include <iostream>
struct A
{
std::string S;
A(const std::string s) { S = s; }
};
void f1(A a) { std::cout << "f1:a.S = " << a.S << "\n"; }
void f1(const std::string s) { std::cout << "f1:s = " << s << "\n"; }
void f2(A a) { std::cout << "f2:a.S = " << a.S << "\n"; }
int main()
{
f1(A("test"));
f1(std::string("test"));
f2(A("test"));
f2(std::string("test"));
return 0;
}
该错误是由f1
创建的被忽略的(由我和编译器(?))模糊引起的 - 函数:f2
清楚地表明f1(A)
和{{1}适用于f1(std::string)
,但在编译时,编译器不会拾取歧义,并且在执行时输出为:
A
这种行为是否正确?编译问题?或者只是普通的旧PIBCAK?
答案 0 :(得分:8)
您所描述的行为是预期的:没有歧义。当两个过载同样匹配并且都是“最佳过载”时,会发生过载分辨率模糊。
当您使用f1
类型的参数调用A
时,第一个f1
是完全匹配的;第二个f1
根本不匹配。因此,f1
显然在重载解析期间获胜。
当您使用f1
类型的参数调用std::string
时,第一个f1
匹配A
的转换构造函数;第二个f1
是完全匹配。第二个f1
是更好的匹配:它是完全匹配,不需要转换。两个重载不能很好地匹配,因此没有歧义。第二个f1
在重载解析期间获胜。