我開始研究CRTP成語,我注意到GCC有一個fdevirtualize
標誌,它應該允許在可能的vtable調用轉換爲直接調用時進行轉換。雖然CRTP可以與任何(C++兼容)編譯器一起使用,但是如果我只想使用gcc進行開發,是否可以避免使用CRTP習慣用法離開gcc進行虛擬化過程,或者在可能的情況下最好使用它,以便使用靜態多態性以避免虛函數調用?CRTP vs GCC中的虛擬化標誌
2
A
回答
4
根據編譯器是否嵌入你的東西,Devirtualization可能有用或不用。
請注意,CRTP通常用於實現mixin和模板方法模式,例如,像這樣:
template <typename T, typename Derived>
class pointer_base {
const Derived& self() const { return static_cast<const Derived&>(*this); }
public:
T& operator *() const { return *self().get(); }
T* operator ->() const { return self().get(); }
};
template <typename T>
class smart_pointer : public pointer_base<T, smart_pointer<T>> {
public:
T* get() const;
};
和虛擬呼叫形式:在任何情況下
template <typename T>
class pointer_base {
protected:
~pointer_base() = default;
public:
virtual T* get() const = 0;
T& operator *() const { return *get(); }
T* operator ->() const { return get(); }
};
template <typename T>
class smart_pointer : public pointer_base<T> {
public:
T* get() const override;
};
用法
smart_pointer<int> p(new int);
*p = 42;
注意,可能有多個不同的智能指針類。在虛函數版本中,它們都來自相同的pointer_base。這意味着所有這些基礎函數都有一個版本可以共享。如果是這種情況,虛擬化就無法工作。
如果有問題的內聯函數到調用它只會工作,因爲那麼編譯器可以將代碼專注於特定的具體的智能指針類型。
當然,如果幫手很小,他們內聯的機率很高。另一方面,您現在擁有一個客戶端可以使用的pointer_base類。你可以從基地私人派生,但是你必須爲每個派生類中要公開的所有成員添加聲明。像pointers_base這樣的類包含很多(我的情況是2,但實際上應該有一個布爾轉換)小函數,這很煩人。但是,CRTP的語法混亂也是如此。我認爲,這歸結爲一個品味問題。
當你只有一個大模板方法時,編譯器不會內聯它。在這種情況下,它不能虛擬化。但CRTP有其自身的缺點:無論您是否需要,該方法都會重複用於每個基本實例。這可能導致代碼膨脹。
所以最終歸結爲模板VS虛函數通常的問題:與其相關的代碼尺寸的增加,或虛擬調用的性能損失,他們豎起了內聯屏障的專業代碼。
相關問題
- 1. CRTP vs過載和最終
- 2. GCC優化標誌
- 3. MVVM vs數據虛擬化
- 4. GCC優化標誌問題
- 5. 隱形GCC優化標誌?
- 6. GCC優化標誌的順序
- 7. '虛擬XYZ' VS 'XYZ虛擬' 方法
- 8. 虛擬機VS.中間件
- 9. 硬件虛擬化
- 10. 相同類中的虛擬方法vs非虛擬方法
- 11. Popup中的UI虛擬化
- 12. gcc彙編標誌
- 13. GCC標誌給SCons
- 14. gcc彙編標誌
- 15. TreeView虛擬化
- 16. 虛擬化WrapPanel
- 17. 虛擬化treelistview?
- 18. 虛擬化NET框架
- 19. 將CRTP與虛擬繼承結合使用
- 20. KVM虛擬化10gbe虛擬以太網
- 21. 虛擬化問題
- 22. 虛擬表單vs Ajax POST
- 23. 性狀vs虛擬開銷
- 24. Pytables vs虛擬內存
- 25. 口譯VS編譯器VS虛擬機
- 26. 靜態鴨打字VS CRTP
- 27. 如何關閉gcc中的特定優化標誌
- 28. GCC連接帶有警告/優化標誌的目標文件
- 29. 託管虛擬機中的I/O虛擬化
- 30. WPF ItemControl虛擬化
很好的解釋,謝謝。 – Jepessen