我在3个不同的编译器(G ++,clang ++,CL.exe)中尝试了以下代码片段,他们都向我报告他们无法消除重载构造函数的歧义。现在,我知道如何修改对构造函数的调用以使其选择一个或另一个(要么明确表示第二个参数是无符号的文字值或显式地转换它)。
但是,我很好奇为什么编译器会首先尝试在构造函数之间进行选择,因为其中一个构造函数是私有的,并且构造函数的调用发生在main函数中,该函数应该在类的范围之外。
任何人都可以开导我吗?
class Test
{
private:
Test(unsigned int a, unsigned int *b) { }
public:
Test(unsigned int a, unsigned int b) { }
};
int main()
{
Test t1 = Test(1,0); // compiler is confused
}
答案 0 :(得分:6)
在C ++中,类成员的可访问性不会影响其他语言语义。相反,任何无效访问都会导致程序格式错误。
换句话说,辅助功能和可见性。标准直接
应该注意,它是对受控制的成员和基类的访问,而不是它们的可见性。成员的名称仍然可见,并且当这些成员和基类不可访问时,仍会考虑对基类的隐式转换。建立对给定构造的解释而不考虑访问控制。如果建立的解释使用了不可访问的成员名称或基类,则该构造是不正确的。
答案 1 :(得分:1)
编译器不会尝试通过其可见性来选择重载的函数或构造函数。
答案 2 :(得分:1)
即使它被标记为私有,编译器也不会拒绝候选函数。这意味着更改成员的可见性不会改变现有代码。
答案 3 :(得分:1)
至于你的第二个问题,重载分辨率在可见性测试之前发生。
首先,您需要向编译器指出0是无符号整数。就编译器而言,从整数0到无符号int的转换并不比从整数0到指针的转换更好。