Форум » C/C++ » Предложение по изменению стандарта C++: адаптеры алгоритмов. » Ответить

Предложение по изменению стандарта C++: адаптеры алгоритмов.

Сыроежка: Нередко при задании в алгоритме предиката получается очень длинное выражение, которое на быстрый взгляд трудно понять. В связи с этим хочу предложить ввести в стандарт C++ адаптеры алгоритмов для следующих типов объектов функций: [pre2] std::equal_to std::not_equal_to std::greater std::less std::greater_equal std::less_equal [/pre2] Например, для стандартного алгоритма std::find_if и в частном случае std::find данное семейство адаптеров алгоритмов будет следующими: [pre2] std::find_equal_to std::find_not_equal_to std::find_greater std::find_less std::find_greater_equal std::find_less_equal [/pre2] Ниже приведена простая демонстрационная программа [pre2] #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"; } }[/pre2] Вывод на консоль может выглядеть примерно следующим образом: [pre2] 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[/pre2]

Ответов - 0



полная версия страницы