Нередко при задании в алгоритме предиката получается очень длинное выражение, которое на быстрый взгляд трудно понять.
В связи с этим хочу предложить ввести в стандарт C++ адаптеры алгоритмов для следующих типов объектов функций:
std::equal_to
std::not_equal_to
std::greater
std::less
std::greater_equal
std::less_equal
Например, для стандартного алгоритма
std::find_if и в частном случае
std::find данное семейство адаптеров алгоритмов будет следующими:
std::find_equal_to
std::find_not_equal_to
std::find_greater
std::find_less
std::find_greater_equal
std::find_less_equal
Ниже приведена простая демонстрационная программа
#include <iostream>
#include <vector>
#include <functional>
#include <iterator>
#include <algorithm>
#include <ctime>
#include <cstdlib>
template <typename InputIterator, typename T>
inline InputIterator find_equal_to( InputIterator first, InputIterator last, const T &value )
{
return std::find( first, last, value );
}
template <typename InputIterator, typename T>
inline InputIterator find_not_equal_to( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::find_if( first, last, std::bind( std::not_equal_to<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline InputIterator find_greater( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::find_if( first, last, std::bind( std::greater<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline InputIterator find_less( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::find_if( first, last, std::bind( std::less<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline InputIterator find_greater_equal( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::find_if( first, last, std::bind( std::greater_equal<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline InputIterator find_less_equal( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::find_if( first, last, std::bind( std::less_equal<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_of_equal_to( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::equal_to<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_not_equal_to( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::not_equal_to<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_of_greater( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::greater<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_of_less( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::less<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_of_greater_equal( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::greater_equal<>(), _1, value ) );
}
template <typename InputIterator, typename T>
inline bool any_of_less_equal( InputIterator first, InputIterator last, const T &value )
{
using namespace std::placeholders;
return std::any_of( first, last, std::bind( std::less_equal<>(), _1, value ) );
}
int main()
{
const size_t N = 10;
std::vector<unsigned int> v;
v.reserve( N );
std::srand( ( unsigned int )std::time( nullptr ) );
std::generate_n( std::back_inserter( v ), N, [] { return std::rand() % N; } );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
unsigned int value = std::rand() % N;
if ( any_of_equal_to( std::begin( v ), std::end( v ), value ) )
{
std::cout << value << " is encountered at position "
<< std::distance( std::begin( v ), find_equal_to( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << value << " has not been found.\n";
}
if ( any_of_not_equal_to( std::begin( v ), std::end( v ), value ) )
{
std::cout << "A value not equal to " << value << " is encountered at position "
<< std::distance( std::begin( v ), find_not_equal_to( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << "A value not equal to " << value << " has not been found.\n";
}
if ( any_of_greater( std::begin( v ), std::end( v ), value ) )
{
std::cout << "A value greater than " << value << " is encountered at position "
<< std::distance( std::begin( v ), find_greater( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << "A value greater than " << value << " has not been found.\n";
}
if ( any_of_less( std::begin( v ), std::end( v ), value ) )
{
std::cout << "A value less than " << value << " is encountered at position "
<< std::distance( std::begin( v ), find_less( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << "A value less than " << value << " has not been found.\n";
}
if ( any_of_greater_equal( std::begin( v ), std::end( v ), value ) )
{
std::cout << "A value greater than or equal to " << value << " is encountered at position "
<< std::distance( std::begin( v ), find_greater_equal( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << "A value greater than or equal to " << value << " has not been found.\n";
}
if ( any_of_less_equal( std::begin( v ), std::end( v ), value ) )
{
std::cout << "A value less than or equal to " << value << " is encountered at position "
<< std::distance( std::begin( v ), find_less_equal( std::begin( v ), std::end( v ), value ) )
<< '\n';
}
else
{
std::cout << "A value less than or equal to " << value << " has not been found.\n";
}
}
Вывод на консоль может выглядеть примерно следующим образом:
6 9 0 2 8 1 2 8 3 4
1 is encountered at position 5
A value not equal to 1 is encountered at position 0
A value greater than 1 is encountered at position 0
A value less than 1 is encountered at position 2
A value greater than or equal to 1 is encountered at position 0
A value less than or equal to 1 is encountered at position 2