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

现在,有下面的代码:

namespace  lx1
{
    
class  Point3d
    {
    
public :
        Point3d (
double  dx,  double  dy,  double  dz)
            : m_dX(dx), m_dY(dy), m_dZ(dz)
        {}

        
double  getX()  const  {  return  m_dX; };
        
double  getY()  const  {  return  m_dY; };
        
double  getZ()  const  {  return  m_dZ; };

    
private :
        
double  m_dX;
        
double  m_dY;
        
double  m_dZ;
    };

    
void  TestPoint( const  Point3d  & pt)
    {
        cout 
<<   " Output from lx1::TestPoint(). "   <<  endl;
    }
}

namespace  lx2
{
    
void  TestPoint( const  lx1::Point3d  & pt)
    {
        cout 
<<   " Output from lx2::TestPoint(). "   <<  endl;
    }

    
void  ShowPoint3d( const  lx1::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++中一条非常容易被忽视的名字查找规则,因此要格外重视。 

你可能感兴趣的:(C++,c,function,编译器)