C ++构造函数重载中的范围和歧义

时间:2010-05-23 16:29:22

标签: c++

我在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
}

4 个答案:

答案 0 :(得分:6)

在C ++中,类成员的可访问性不会影响其他语言语义。相反,任何无效访问都会导致程序格式错误。

换句话说,辅助功能可见性。标准直接

  

应该注意,它是对受控制的成员和基类的访问,而不是它们的可见性。成员的名称仍然可见,并且当这些成员和基类不可访问时,仍会考虑对基类的隐式转换。建立对给定构造的解释而不考虑访问控制。如果建立的解释使用了不可访问的成员名称或基类,则该构造是不正确的。

答案 1 :(得分:1)

编译器不会尝试通过其可见性来选择重载的函数或构造函数。

答案 2 :(得分:1)

即使它被标记为私有,编译器也不会拒绝候选函数。这意味着更改成员的可见性不会改变现有代码。

答案 3 :(得分:1)

至于你的第二个问题,重载分辨率在可见性测试之前发生。

首先,您需要向编译器指出0是无符号整数。就编译器而言,从整数0到无符号int的转换并不比从整数0到指针的转换更好。