1

下面是一些C++的編程語言語用模板代碼,由斯科特·何時進行類型參數的類型檢查?

template<typename T> 
class chooser { 
    public: 
    virtual bool operator()(const T& a, const T& b) = 0; 
}; 

template<typename T, typename C> 
class arbiter { 
    T* best_so_far; 
    C comp; 
public: 
    arbiter() { best_so_far = nullptr; } 
    void consider(T* t) { 
     if (!best_so_far || comp(*t, *best_so_far)) best_so_far = t; 
    } 
    T* best() { 
     return best_so_far; 
    } 
}; 

class case_sensitive : chooser<string> { 
public: 
    bool operator()(const string& a, const string& b) { return a < b; } 
}; 
... 
arbiter<string, case_sensitive> cs_names; // declare new arbiter 
cs_names.consider(new string("Apple")); 
cs_names.consider(new string("aardvark")); 
cout << *cs_names.best() << "\n"; // prints "Apple" 

C++編譯器,每次我們有一個聲明的對象(例如,cs_names)時將創建arbiter 模板的新實例 不同的一組泛型參數。 只有當我們嘗試使用這種 的對象(例如,通過調用consider)將它檢查看 論據是否支持所有需要的操作。

因爲類型檢查被延遲,直到使用點,沒有什麼神奇的 有關chooser類。如果我們忽略定義它,然後將其從case_sensitive的標頭 中刪除,則代碼 仍會編譯並運行。

在編譯時或以下兩個時間點運行時間:

  • 的時間「當我們試圖用這樣一個對象」和

  • 「使用點」 ?

「類型檢查延遲到使用點」是否意味着類型檢查是在運行時完成的?

謝謝。

回答

2
  • 的時間「當我們試圖用這樣一個對象」和
  • 「使用點」?

兩者都指源代碼,而不是運行時。

在這一行:

arbiter<string, case_sensitive> cs_names; 

編譯器遇到std::stringcase_sensitive,並試圖實現與Tcase_sensitive替代版本的arbiter通過std::stringC取代。

如果使用其他類型定義另一個arbiter,將生成並編譯新版本的arbiter

0

阿蘭擁有的權利。

供將來參考C++,在一般情況下,編譯時檢查的一切。我知道的唯一例外是多態類型的動態轉換和函數typeid,它返回一個對象的類型。

在我看來,如果你使用過這些功能,你通常應該重新考慮你的O-O設計。(或者你正試圖解決別人的破壞代碼而不重構)。