C で特定の型のみを受け入れるようにテンプレートを制約する方法
Java では、継承する型のみを受け入れるようにジェネリック クラスを定義できます。特定のクラスから:
public class ObservableList<T extends List> { /* ... */ }
これは extends を使用して実現されます。キーワード.
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 中国語 Web サイトの他の関連記事を参照してください。