Ambiguity not picked up by compiler

☆樱花仙子☆ 提交于 2019-12-10 18:37:15

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!