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

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



ссылка на сообщение  Отправлено: 28.07.12 19:08. Заголовок: Пример преимуществ лямбда выражений


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

Но есть одна область применения лямбда выражений, где их использование имеет несомненно большой плюс. Это использование лямбда выражений не сразу же приходит на ум, поэтому я решил им поделиться.

Иногда приходится объявлять функции, которые в качестве параметра имеют указатель на другую функцию. Типичным примером является стандартная функция библиотеки С .qsort, которая имеет следующее объявление

void qsort( void *base, size_t nelem, size_t width, int ( *compare )( const void *, const void * ) );

В этом объявлении compare - это указатель на функцию, принимающую два параметра - два указателя - и возвращающую значение типа int.

Например, чтобы отсортировать массив целых чисел, вы в качестве такого параметра могли бы передать функцию

 int less( const void *left, const void *right ) 
{
return ( *( int * )left - *( int * )right );
}


И тогда бы функция qsort отсортировала ваш массив по возрастанию значений элементов.

В пользовательском коде также нередко встречаются объявления функций, которые в качестве параметра принимают указатель на другую функцию. При этом порой желательно задать аргумент по умолчанию для такого параметра. Раньше, до принятия нового стандарта С++ это делалось примерно так.

 void h( int x ) 
{
std::cout << x << std::endl;
}

void f( int x, void ( *pf )( int ) = h )
{
pf( x );
}


В чем недостаток этого подхода?
Во-первых, вам нужно указать конкретное имя функции в качестве аргумента по умолчанию. А это может привести к конфликту имен. Вы тем самым "засоряете" пространство имен именем, единственная цель объявления которого, это использование в качестве аргумента по умолчанию.
Во-вторых, между объявлением функции, используемой в качестве аргумента по умолчанию, и функцией, которая ее использует, может находиться много строчек кода, а то и вообще они могут располагаться в разных модулях, а это затрудняет чтение кода, так как вы не будете иметь представление о том, а что же делает этот аргумент по умолчанию, достаточно ли его использовать при вызове функции, или же этот аргумент по умолчанию следует заменить своей функцией.

Эти проблемы очень просто решаются с помощью лямбда выражений!

Предудыщее объявление функции f можно переписать следующим образом, используя в ее объявлении лямбда выражение:

 void f( int x, void h( int ) = [] ( int x ) { std::cout << x << std::endl; } ) 
{
h( x );
}


Здесь сразу же наглядно видны преимущества этого подхода. Во-первых, нам доступна информация о том, что делает функция, заданная в качестве аргумента по умолчанию. Нам не надо искать ее определение, как это имело место в предыдущем примере, чтобы выяснить, что же все-таки делает функция, заданная в качестве аргумента по умолчанию.
Во-вторых, мы не вводим новое имя в пространство имен, так как имя параметра h имеет лишь локальную область видимости внутри блока кода тела функции f.

Естественно этот подход выгоден в тех случаях, когда тело такой функции достаточно простое. Но как раз для функций, используемых в качестве аргументов по умолчанию для других функций, этого условие обычно выполняется.

Напомню, что этот код не будет компилироваться на MS VC++ 2010, так как этот компилятор не поддерживает функцию преобразования лямбда выражения в указатель на функцию. Об этом я писал в темах, посвященных багам MS VC++ 2010.

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


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

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