如何在 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中文网其他相关文章!