C 的強大功能之一,奇怪的循環模板模式(CRTP),支援靜態多態性性。這允許編譯時靈活地確定基於模板參數創建的物件的類型。然而,擴展 CRTP 以允許基於派生類型修改函數傳回類型是一個挑戰。
考慮以下嘗試泛化 CRTP 的程式碼:
template <typename derived_t> class base { public: typedef typename derived_t::value_type value_type; value_type foo() { return static_cast<derived_t*>(this)->foo(); } }; template <typename T> class derived : public base<derived<T>> { public: typedef T value_type; value_type foo() { return T(); } };
此程式碼無法編譯Microsoft Visual Studio 2010 由於錯誤:「value_type」不是以下成員'衍生
這個問題源自於以下事實:當用作基底類別清單中的基底的範本參數時,衍生是不完整的。為了解決這個問題,常見的解決方法是使用特徵類別模板。
引入base_traits 模板:
template <typename derived_t> struct base_traits;
使用特徵重新定義基類:
template <typename derived_t> struct base { typedef typename base_traits<derived_t>::value_type value_type; value_type base_foo() { return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this)); } };
並專門化派生的base_traits:
template <typename T> struct base_traits<derived<T> > { typedef T value_type; static value_type call_foo(derived<T>* x) { return x->derived_foo(); } };
這種方法允許透過特徵使用衍生類別的類型和函數。透過為每個模板參數專門化 base_traits,您可以為每個衍生類別提供所需的成員。
以上是在 C 衍生類別中使用 CRTP 和 Typedef 時如何解決編譯時錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!