如何在 C 中約束模板僅接受特定類型
在 Java中,可以將泛型類別定義為僅接受繼承的類型來自特定類別:
public class ObservableList<T extends List> { /* ... */ }
這是使用擴展來實現的
C 中的等效項
與Java 不同,C 沒有與用於約束模板的extends 關鍵字直接等效的內容。然而,有一種方法可以使用C 11 中的std::is_base_of 類型特徵來實現類似的限制:
#include <type_traits> template<typename T> class observable_list { static_assert(std::is_base_of<list, T>::value, "T must inherit from list"); // code here.. };
替代方法
雖然這種方法有效,它脫離了典型的C 設計原則。相反,使用基於特徵的限制可能更合適:
#include <type_traits> template<typename T> class observable_list { static_assert(has_const_iterator<T>::value, "Must have a const_iterator typedef"); static_assert(has_begin_end<T>::value, "Must have begin and end member functions"); // code here... }; template<typename T> struct has_const_iterator : std::false_type {}; template<typename T> struct has_const_iterator<T, Void<typename T::const_iterator>> : std::true_type {}; struct has_begin_end_impl { template<typename T, typename Begin = decltype(std::declval<const T&>().begin()), typename End = decltype(std::declval<const T&>().end())> static std::true_type test(int); template<typename... Args> static std::false_type test(...); }; template<typename T> struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {}; using Void = typename void_<>::type; template<typename... Args> struct void_ { using type = void; };
此方法定義自訂特徵來檢查特定要求(例如,const_iterator、begin 和 end 函數是否存在)。它提供了更大的靈活性並允許自訂錯誤訊息。
以上是如何將 C 中的範本類型限制為特定的繼承或功能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!