C++14中如何编写仅支持vector和valarray的通用模板消除代码重复
解决方案
你预想的写法需要使用模板模板参数实现,C++14标准没有concept约束,可以通过SFINAE机制实现容器类型的白名单限制,只允许std::vector和std::valarray匹配,彻底消除重复代码。
可直接复用的实现代码
#include <vector> #include <valarray> #include <type_traits> // 定义允许传入的容器白名单特征 template <template <class...> class C> struct is_allowed_container : std::false_type {}; template <> struct is_allowed_container<std::vector> : std::true_type {}; template <> struct is_allowed_container<std::valarray> : std::true_type {}; // 统一的foo函数实现 template <class T, template <class...> class Container> std::enable_if_t<is_allowed_container<Container>::value> foo(Container<T>* p) { // 此处填写两个重载完全一致的函数体逻辑即可 }
实现说明
- 模板参数
template <class...> class Container是模板模板参数,能够匹配std::vector、std::valarray这类本身是模板的类型,适配你预期的Container<T>写法,变长参数声明可以兼容不同模板默认参数的差异,兼容性更强。 - 对
is_allowed_container做偏特化标记白名单类型,非白名单容器传入时,SFINAE规则会让该模板匹配失败,直接触发编译错误,不会产生非法实例,完全满足你的类型约束要求。 - 该实现是纯编译期逻辑,没有任何运行时开销,和你手写两个重载的运行表现完全一致。
如果不想单独定义类型特征,也可以直接在enable_if中写判断逻辑,代码更短:
template <class T, template <class...> class Container> auto foo(Container<T>* p) -> std::enable_if_t< std::is_same<Container<T>, std::vector<T>>{} || std::is_same<Container<T>, std::valarray<T>>{} > { // 统一函数体逻辑 }
注意:你最初预想的
template <class T, class Container> void foo(Container<T>* p)写法无法编译,因为这里的Container是普通类型参数而非模板模板参数,编译器无法识别Container<T>的模板调用语法。
内容的提问来源于stack exchange,提问作者P45 Imminent
相关产品推荐
相关产品推荐

