在使用模板的时候,我们往往需要针对特殊的类型进行特殊的处理,特殊情况特殊处理,因此就产生了特化模板这个概念
理解起来很简单,STL库学过C++的应该没少用,遇到问题去看源码一看一堆知识点,sort排序的话是借助比较器对参数进行比较的,如果比较的对象是pair这种数据的话呈现出的效果需要和一般数据类型不同,使用sort的时候参数可以用两个也可以用三个,这些都是借助特化实现的
泛型版本
sort泛型模板,_RanIt需要是迭代器类型,_Pr需要是比较器类型,类型检测放代码里了,sort的参数瞎传会在运行期间报错,提示没有可用的重载
template <class _RanIt, class _Pr>
_CONSTEXPR20 void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) { // order [_First, _Last)
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_Sort_unchecked(_UFirst, _ULast, _ULast - _UFirst, _Pass_fn(_Pred));
}
less比较器泛型模板,三个typedef的作用是为了兼容C++17之前的版本,C++17之后这些东西不会编译,这里上下文信息较少这里就不作分析了,作用应该是保证仿函数的参数和返回值是正确的
template <class _Ty = void>
struct less {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _FIRST_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _SECOND_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool _RESULT_TYPE_NAME;
_NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const {
return _Left < _Right;
}
};
全特化
less比较器全特化模板,void版本调用的时候使用less<>,这段代码已经高度现代化了,使用了返回值后置是为了保证先进行noexcept的检测,别的地方我在前面的博客中已经讲过了这里就不一 一解释了
template <>
struct less<void> {
template <class _Ty1, class _Ty2>
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
noexcept(noexcept(static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right))) // strengthened
-> decltype(static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right)) {
return static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right);
}
using is_transparent = int;
};
偏特化(部分特化)
sort偏特化模板,将比较器类型设置默认类型less<>,之所以不在模板中直接定义默认值我觉得是一种优化,跳过了繁琐的比较器检测过程
template <class _RanIt>
_CONSTEXPR20 void sort(const _RanIt _First, const _RanIt _Last) { // order [_First, _Last)
_STD sort(_First, _Last, less<>{});
}
简单的说泛型就是模板的基类型,特化是对基类型的一种补充用于处理各种特殊的情况,全特化处理具体情况,偏特化处理模糊的情况