C++中一个容易被忽视的名字查找规则
生活随笔
收集整理的這篇文章主要介紹了
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++中一條非常容易被忽視的名字查找規則,因此要格外重視。
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++中一个容易被忽视的名字查找规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是802.11G协议
- 下一篇: 《演讲之禅》助你成长为一名合格程序员