C++中一个容易被忽视的名字查找规则

本文探讨了一段看似无误但无法通过编译的C++代码,揭示了在不同命名空间中函数重名导致的编译错误,并解释了C++中特殊的名字查找规则。

现在,有下面的代码:

namespacelx1
{
classPoint3d
{
public:
Point3d(
doubledx,doubledy,doubledz)
:m_dX(dx),m_dY(dy),m_dZ(dz)
{}

doublegetX()const{returnm_dX;};
doublegetY()const{returnm_dY;};
doublegetZ()const{returnm_dZ;};

private:
doublem_dX;
doublem_dY;
doublem_dZ;
};

voidTestPoint(constPoint3d&pt)
{
cout
<<"Outputfromlx1::TestPoint()."<<endl;
}
}

namespacelx2
{
voidTestPoint(constlx1::Point3d&pt)
{
cout
<<"Outputfromlx2::TestPoint()."<<endl;
}

voidShowPoint3d(constlx1::Point3d&pt)
{
TestPoint(pt);

cout
<<"X:"<<pt.getX()<<endl;
cout
<<"Y:"<<pt.getY()<<endl;
cout
<<"Z:"<<pt.getZ()<<endl;
}
}

你能发现代码中有什么问题吗?
上面的代码看上去没有什么问题,却不能通过编译,会得到一个“'lx2::TestPoint' : ambiguous call to overloaded function”的错误。也就是说编译器不能确定在ShowPoint3d()函数中调用的是哪个TestPoint()函数。
也许你会非常不解,为什么会出现这样的编译错误。在命名空间lx2中只有一个函数TestPoint(),为什么编译器会不能确定调用哪个TestPoint()函数呢?虽然在命名空间lx1中有一个跟lx2中参数列表相同的TestPoint()函数,可是在命名空间lx2中并没有用using namespace lx1;这样的语句,编译器应该不会去命名空间lx1中去匹配TestPoint()函数呀。
事实上,出现编译错误的原因就是在命名空间lx1和lx2里面都有一个函数列表相同的TestPoint()函数。
在C++中有这样一个名字查找规则--如果在声明函数的参数时使用了一个类,那么在查找匹配的函数名字时,编译器会在包含参数类型的名字空间中也进行查找
在上面的代码中,命名空间lx2中的TestPoint()函数参数是lx1::Point3d。按照上面的规则,编译器在查找匹配的函数名字时,也会去包含参数Point3d的名字空间(也就是lx1)中进行匹配查找。而在命名空间lx1中也有一个参数列表跟命名空间lx2中一样的TestPoint()函数,所以会出现上面的编译错误。
这是C++中一条非常容易被忽视的名字查找规则,因此要格外重视。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值