源码分析for_each,unique,stable_sort,find_if
unique
这个函数只能对"相同元素在并邻在一块的"序列进行去重. 不能对相同元素七零八落地分布的一般序列进行去重, 可以对一般数组进行排序后再用unique()实现去重目的即可, 因为排好序的的序列里面相同元素一定存储在连续的地址块. 提醒, 该函数实现去重功能并不是把相同元素删除
返回的是不重复元素的最后一个不包括自己,在容器里都是维持着左闭右开的区间
unique的源码解析
unique(_ForwardIterator __first, _ForwardIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_function_requires(_EqualityComparableConcept<
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__unique(__first, __last,
__gnu_cxx::__ops::__iter_equal_to_iter());
}
_unique(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
{
// Skip the beginning, if already unique.
__first = std::__adjacent_find(__first, __last, __binary_pred);
if (__first == __last)
return __last;
// Do the real copy work.
_ForwardIterator __dest = __first;
++__first;
while (++__first != __last)
if (!__binary_pred(__dest, __first))
*++__dest = _GLIBCXX_MOVE(*__first);
return ++__dest;
}
其实关键就在于
while (++__first != __last)
if (!__binary_pred(__dest, __first))
*++__dest = _GLIBCXX_MOVE(*__first);
return ++__dest;
去掉重命名和宏替换以后
while (++__first != __last)
if (__dest != __first))
*++__dest = std::move(*__first);
return ++__dest;
其实就是每一次去找后面不同的进行替换
比如 1 2 2 2 4 4 5 下标在 0 1这时候 0 1 对应数值不相等所以 *++dest =*first就相当于没有交换
1 2 2 2 4 4 5 下标分别在 1 2相等继续++first,直到first到达下标4交换
1 2 4 2 4 4 5 下标为 2 5 又相等 ++first
1 2 4 2 4 4 5 下标 2 6 不等 *dest = *first
1 2 4 5 4 4 5 下标 3 6 这时候++first到达终点返回 ++dest也就返回下标在4的迭代器
for_each()
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
}
其实就是执行可调用表达式进行调用,参数就是每一个迭代器里面的内容
find_if
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__pred_iter(__pred));
}
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred, input_iterator_tag)
{
while (__first != __last && !__pred(__first))
++__first;
return __first;
}
其实就是找到满足可调用表达式里面第一个条件的迭代器
可调用表达式包括,函数,函数指针,std::bind,lambda表达式,重载()调用运算符的类