2016-09-28 184 views
3

我正在研究two phase name lookup。一個非常合乎邏輯的解釋表明,one of the main reasoning是因爲它遵循C++哲學儘早捕獲錯誤實例化模板化類的非模板化非模板化方法

我的問題是,爲什麼沒有這個理念,遵循非模板的方法。而不是檢查何時以及是否調用方法,爲什麼不檢查模板類實例化時階段2中的所有非模板化方法?

例如爲:

template <class T> 
struct X { 

    auto foo() // non-templated (important) 
    { 
    T t{}; 
    return t.non_existing(); 
    } 
}; 

int main() 
{ 
    X<int> x; // (1) this compiles OK. 

    // somewhere is a galaxy far far away, 
    // maybe deep inside some unrelated code 
    x.foo(); // (2) the error is here 
} 

如果你從來不寫(2)程序編譯並沒有任何問題上運行,雖然foo是實例化X<int>非法的。

我認爲線(1)應產生的錯誤,無論如果你打電話foo與否。

在編寫模板類,這可以讓漏網之魚裂縫的錯誤,直到你最終調用該方法存在問題(2),而不是得到的錯誤,當你實例化模板類(1)。

此外,健全性檢查:如果我實例化X<int>(1)但從未呼叫X<int>::foo(2),代碼是否有效?還是像「不合格,不需要診斷」?如果是後者,那麼這是更早發現錯誤的更多理由。

+0

完整性檢查:代碼(1)有效。至於爲什麼:想象一下,如果你不得不爲非可複製的'T's禁用'std :: vector ',就要寫一個拷貝構造函數。 Dtto for'push_back(const T&)'等 – Angew

+0

@Angew我想象的是通過禁用SFINAE方法來管理。 – bolov

回答

6

代碼有效。

此功能旨在允許std::vector有一個簡單的operator<operator==

該運營商將試圖調用<==其元素,一味。如果它是無效的,一旦你在包裝vector上調用<==,它將無法編譯。

但是,如果你從來沒有,在vector將正常工作。

現代C++會建議使用SFINAE條件方法技術或C++ 20需要條款,從而vector只會一個==<,如果它是一個有效的操作。這些技術都沒有成熟,當設計vector時,以及具有無效的模板類方法的能力是重要特徵。

除了無效代碼早期失敗之外,有條件地存在==允許包裝代碼檢測==是否可以安全調用:古老的技術不允許這種內省。我不得不編寫專門針對標準容器模板的自定義特徵來檢測至少有一種情況是否可以安全地調用<