2008-10-17 40 views
1

我有一個很大的代碼庫,包含兩個主要的命名空間:引擎和應用程序。函數重載失敗:這些操作符爲什麼發生衝突?

發動機的Vector3一類定義爲另一個的Vector3類的一個typedef,具有相等運算坐在發動機的命名空間,而不是在的Vector3類。我向應用程序名稱空間中也有等號運算符的應用程序添加了一個類。

當我試圖編譯,但無關近的Vector3通過比較失敗,因爲它找不到一個合適的相等運算符。我懷疑我正在引起衝突,所以將我的平等操作員移到我添加的班級中,並且編譯成功。

// engine.h 
namespace Engine 
{ 
    class Vector3Impl { ... }; 
    typedef Vector3Impl Vector3; 
    bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... } 
} 


// myfile.cpp 
#include "engine.h" 

namespace application 
{ 
    class MyClass { ... }; 
    bool operator==(MyClass const &lhs, MyClass const &rhs) { ... } 

    void myFunc(...) 
    { 
     if (myClassA == myClassB) { ... } // builds 
    } 

    void anotherFunc(...) 
    { 
     Engine::Vector3 a, b; 
     ... 
     if (a == b) { ... } // fails 
    } 
} 

然而,想到它後,我看不出爲什麼編譯失敗。沒有從vector3s到我的類的隱式轉換,反之亦然,並且依賴於參數的查找應該從引擎名稱空間拉入相等運算符並匹配它。

我試圖再現一個C++項目這個bug但拒絕打破。在導致這個問題的大型代碼庫中肯定有一些東西,但我不確定從哪裏開始尋找。類似於使用引擎的流氓的對立面?任何人有任何想法?

回答

2

C++標準,3.4.4.2宣告:

對於在函數調用每個參數類型T,有一組零個或多個相關聯的命名空間和一組零 或多個相關聯的類是考慮。命名空間和類的集合完全由函數參數(和任何模板模板參數的名稱空間)的類型 確定。 Typedef名稱和使用聲明 用於指定類型不參與此設置

ADL沒有用typedef的工作。

-1
bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... } 

在一個類上定義的相等運算符的規範定義應該只有一個參數,即rhs。 lhs就是這樣。 不知道這是否會解決您的問題。

這是我會寫:

類的Vector3 { 布爾運算符==(常量的Vector3 &右)const的{...}} ;

+0

我相信tenpn在封閉的命名空間中記下了他的初始代碼 - 帶有在類之外定義的運算符。 – xtofl 2008-10-17 08:36:22

+0

編寫一個獨立運算符==有兩個參數是沒有問題的。它的優點是允許對第一個參數進行隱式轉換,如果它們是如此期望的話。 – Gorpik 2008-10-17 08:45:32

0

有一次,我碰到了一個編譯器,沒有參數依賴查找(Koenig查找 - 感謝@igor)同樣的問題(VC6我認爲)。這意味着當它看到一個操作符時,它只是查找封閉的命名空間。

所以,你能告訴我們你用什麼編譯器?

移動到另一個編譯器解決了它。

的確很不方便。