所在头文件
#include <algorithm>
注:自定义类要使用find与find_if函数需要重载==运算符函数
find
函数说明
寻找指向与value相等的元素
函数声明
template <class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T & value);
template< class InputIt, class T >
constexpr InputIt find( InputIt first, InputIt last, const T& value );
返回值
返回一个指向与value相等元素的迭代器
底层实现
//version1
template<class InputIt, class T>
constexpr InputIt find(InputIt first, InputIt last, const T& value)
{
for (; first != last; ++first) {
if (*first == value) {
return first;
}
}
return last;
}
//version2
template<typename _InputIterator, typename _Tp>
inline _InputIterator
find(_InputIterator __first, _InputIterator __last,
const _Tp& __val)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_EqualOpConcept<
typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__iter_equals_val(__val));
}
以下四行为合法性判断
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_EqualOpConcept<
typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
在version2的实现中,find的实现调用了find_if
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__iter_equals_val(__val));
iter_equals_val为一个返回值为bool类型的函数对象,其实现为
template<typename _Value>
inline _Iter_equals_val<_Value>
__iter_equals_val(_Value& __val)
{ return _Iter_equals_val<_Value>(__val); }
template<typename _Iterator1>
struct _Iter_equals_iter
{
_Iterator1 _M_it1;
explicit
_Iter_equals_iter(_Iterator1 __it1)
: _M_it1(__it1)
{ }
template<typename _Iterator2>
bool
operator()(_Iterator2 __it2)
{ return *__it2 == *_M_it1; }
};
函数调用运算符调用了容器内类的==运算符函数,因此若为自定义类需要重载==运算符
operator()(_Iterator2 __it2)
{ return *__it2 == *_M_it1; }
实例
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v{1, 2, 3, 4};
int n1 = 3;
int n2 = 5;
auto is_even = [](int i){ return i%2 == 0; };
auto result1 = std::find(begin(v), end(v), n1);
auto result2 = std::find(begin(v), end(v), n2);
auto result3 = std::find_if(begin(v), end(v), is_even);
(result1 != std::end(v))
? std::cout << "v contains " << n1 << '\n'
: std::cout << "v does not contain " << n1 << '\n';
(result2 != std::end(v))
? std::cout << "v contains " << n2 << '\n'
: std::cout << "v does not contain " << n2 << '\n';
(result3 != std::end(v))
? std::cout << "v contains an even number: " << *result3 << '\n'
: std::cout << "v does not contain even numbers\n";
}
find_if
函数说明
寻找第一个指向符合断言函数的元素
函数声明
template <class InputIterator, class UnaryPredicate>
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
返回值
返回指向第一个符合断言函数元素的迭代器
底层实现
template<class InputIt, class UnaryPredicate>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
//遍历整个容器,若出现符合断言函数条件的元素,直接返回其迭代器
for (; first != last; ++first) {
if (p(*first)) {
return first;
}
}
return last;
}
实例
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v{1, 2, 3, 4};
int n1 = 3;
int n2 = 5;
auto is_even = [](int i){ return i%2 == 0; };
auto result1 = std::find(begin(v), end(v), n1);
auto result2 = std::find(begin(v), end(v), n2);
auto result3 = std::find_if(begin(v), end(v), is_even);
(result1 != std::end(v))
? std::cout << "v contains " << n1 << '\n'
: std::cout << "v does not contain " << n1 << '\n';
(result2 != std::end(v))
? std::cout << "v contains " << n2 << '\n'
: std::cout << "v does not contain " << n2 << '\n';
(result3 != std::end(v))
? std::cout << "v contains an even number: " << *result3 << '\n'
: std::cout << "v does not contain even numbers\n";
}