C++中一个容易被忽视的名字查找规则
生活随笔
收集整理的這篇文章主要介紹了
C++中一个容易被忽视的名字查找规则
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
現(xiàn)在,有下面的代碼:
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;}}你能發(fā)現(xiàn)代碼中有什么問題嗎?上面的代碼看上去沒有什么問題,卻不能通過編譯,會(huì)得到一個(gè)“'lx2::TestPoint' : ambiguous call to overloaded function”的錯(cuò)誤。也就是說編譯器不能確定在ShowPoint3d()函數(shù)中調(diào)用的是哪個(gè)TestPoint()函數(shù)。也許你會(huì)非常不解,為什么會(huì)出現(xiàn)這樣的編譯錯(cuò)誤。在命名空間lx2中只有一個(gè)函數(shù)TestPoint(),為什么編譯器會(huì)不能確定調(diào)用哪個(gè)TestPoint()函數(shù)呢?雖然在命名空間lx1中有一個(gè)跟lx2中參數(shù)列表相同的TestPoint()函數(shù),可是在命名空間lx2中并沒有用using namespace lx1;這樣的語句,編譯器應(yīng)該不會(huì)去命名空間lx1中去匹配TestPoint()函數(shù)呀。事實(shí)上,出現(xiàn)編譯錯(cuò)誤的原因就是在命名空間lx1和lx2里面都有一個(gè)函數(shù)列表相同的TestPoint()函數(shù)。在C++中有這樣一個(gè)名字查找規(guī)則--如果在聲明函數(shù)的參數(shù)時(shí)使用了一個(gè)類,那么在查找匹配的函數(shù)名字時(shí),編譯器會(huì)在包含參數(shù)類型的名字空間中也進(jìn)行查找。在上面的代碼中,命名空間lx2中的TestPoint()函數(shù)參數(shù)是lx1::Point3d。按照上面的規(guī)則,編譯器在查找匹配的函數(shù)名字時(shí),也會(huì)去包含參數(shù)Point3d的名字空間(也就是lx1)中進(jìn)行匹配查找。而在命名空間lx1中也有一個(gè)參數(shù)列表跟命名空間lx2中一樣的TestPoint()函數(shù),所以會(huì)出現(xiàn)上面的編譯錯(cuò)誤。這是C++中一條非常容易被忽視的名字查找規(guī)則,因此要格外重視。
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;}}你能發(fā)現(xiàn)代碼中有什么問題嗎?上面的代碼看上去沒有什么問題,卻不能通過編譯,會(huì)得到一個(gè)“'lx2::TestPoint' : ambiguous call to overloaded function”的錯(cuò)誤。也就是說編譯器不能確定在ShowPoint3d()函數(shù)中調(diào)用的是哪個(gè)TestPoint()函數(shù)。也許你會(huì)非常不解,為什么會(huì)出現(xiàn)這樣的編譯錯(cuò)誤。在命名空間lx2中只有一個(gè)函數(shù)TestPoint(),為什么編譯器會(huì)不能確定調(diào)用哪個(gè)TestPoint()函數(shù)呢?雖然在命名空間lx1中有一個(gè)跟lx2中參數(shù)列表相同的TestPoint()函數(shù),可是在命名空間lx2中并沒有用using namespace lx1;這樣的語句,編譯器應(yīng)該不會(huì)去命名空間lx1中去匹配TestPoint()函數(shù)呀。事實(shí)上,出現(xiàn)編譯錯(cuò)誤的原因就是在命名空間lx1和lx2里面都有一個(gè)函數(shù)列表相同的TestPoint()函數(shù)。在C++中有這樣一個(gè)名字查找規(guī)則--如果在聲明函數(shù)的參數(shù)時(shí)使用了一個(gè)類,那么在查找匹配的函數(shù)名字時(shí),編譯器會(huì)在包含參數(shù)類型的名字空間中也進(jìn)行查找。在上面的代碼中,命名空間lx2中的TestPoint()函數(shù)參數(shù)是lx1::Point3d。按照上面的規(guī)則,編譯器在查找匹配的函數(shù)名字時(shí),也會(huì)去包含參數(shù)Point3d的名字空間(也就是lx1)中進(jìn)行匹配查找。而在命名空間lx1中也有一個(gè)參數(shù)列表跟命名空間lx2中一樣的TestPoint()函數(shù),所以會(huì)出現(xiàn)上面的編譯錯(cuò)誤。這是C++中一條非常容易被忽視的名字查找規(guī)則,因此要格外重視。
總結(jié)
以上是生活随笔為你收集整理的C++中一个容易被忽视的名字查找规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是802.11G协议
- 下一篇: c++中的void指针和const指针