On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 19.09.18 15:55. Заголовок: Предложение по изменению стандарта C++: адаптеры алгоритмов.


Нередко при задании в алгоритме предиката получается очень длинное выражение, которое на быстрый взгляд трудно понять.

В связи с этим хочу предложить ввести в стандарт 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


Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 31
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет