c++ - 为什么这些重载函数调用不明确?

标签 c++ implicit-conversion overload-resolution

为什么以下重载函数调用不明确?编译错误:

call of overloaded 'test(long int)' is ambiguous,candidates are: void test(A)| void test(B)|

代码:

class A
{
    public:
        A(int){}
        A(){}
};

class B: public A
{
    public:
        B(long){}
        B(){}
};

void test(A a)
{
}

void test(B b)
{
}

void main()
{
    test(0L);
    return;
}

最佳答案

你得到了一个错误,因为重载决议必须从两个同样可行的函数中选择(都有用户定义的转换)。函数重载决议是一个非常复杂的主题。有关重载决议的更多详细信息,请参见例如这个recent lecture斯蒂芬·T·拉瓦维 (Stephan T. Lavavej)。通常最好使单参数构造函数显式,然后使用显式构造函数参数调用您的函数。

test(0L) 与任何重载都不完全匹配,因为没有重载 test(long)。您提供的两个重载都对它们的参数进行了用户定义的转换,但编译器认为它们同样可行。 A 重载必须执行标准转换(long 到 int),然后执行用户定义的转换(int 到 A),B 重载用户定义的转换(长到 B)。但两者都是隐式用户定义的转换序列

这些排名如何?该标准在13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]

中说

Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 is a proper subsequence of S2

这些类型的打破平局,例如如果 A 是 B 的派生类(反之亦然),则适用。但是这里两个转换序列都不是另一个的子序列。因此它们同样可行,编译器无法解析调用。

class A
{
public:
    explicit A(int){}
    A(){}
};

class B: public A
{
public:
    explicit B(long){}
    B(){}
};

void test(A a)
{}

void test(B b)
{}

int main()
{
    test(A(0L));  // call first overload
    test(B(0L)); // call second overload
    return 0;
}

注意:它是 int main(),而不是 void main()

关于c++ - 为什么这些重载函数调用不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11880585/

相关文章:

c++ - 使用带有冗余信息的键字符串的 map ?

c++ - 模板重载解析和隐式转换

c++ - 将重载函数传递给另一个函数时如何指定重载?

java - 为什么 Java 选择这个重载而不是其他重载

c++ - 将 Bitmap 转换为 unsigned char vector

c++ - 有没有办法使用 typedef 中的参数名称

unsigned long 乘以 float 会变成负数吗?

c++ - 过载解析的问题

c++ - 优化 Stack-Walking 性能

c - 用显式转换替换隐式转换有任何副作用吗?