问题
I had to spent some time in finding and fixing a bug that I managed to isolate in the following code:
#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;
}
The bug was caused by the overlooked (by me and the compiler(?)) ambiguity created by the f1
-function: f2
clearly shows that both f1(A)
and f1(std::string)
apply to A
, but when compiled the ambiguity is not picked-up by the compiler, and when executed the output is:
f1:a.S = test
f1:s = test
f2:a.S = test
f2:a.S = test
Is this behavior correct? Compiler problem? Or just plain old PIBCAK?
回答1:
The behavior that you describe is expected: there is no ambiguity. An overload resolution ambiguity occurs when two overloads match equally well and are both "the best overload."
When you call f1
with an argument of type A
, the first f1
is an exact match; the second f1
does not match at all. Thus, f1
obviously wins during overload resolution.
When you call f1
with an argument of type std::string
, the first f1
matches via the converting constructor of A
; the second f1
is an exact match. The second f1
is a better match: it's an exact match and no conversion is required. The two overloads do not match equally well, thus there is no ambiguity. The second f1
wins during overload resolution.
来源:https://stackoverflow.com/questions/13554606/ambiguity-not-picked-up-by-compiler