Связать Vs Лямбда?

У меня вопрос о том, какой стиль предпочтительнее: std :: bind Vs lambda в C ++ 0x. Я знаю, что они служат – как-то – разные цели, но позволяют взять пример пересекающихся функций.

Использование lambda :

 uniform_int distribution(1, 6); mt19937 engine; // lambda style auto dice = [&]() { return distribution(engine); }; 

Использование bind :

 uniform_int distribution(1, 6); mt19937 engine; // bind style auto dice = bind(distribution, engine); 

Какой из них мы предпочитаем? Зачем? предполагая более сложные ситуации по сравнению с указанным примером. т.е. каковы преимущества / недостатки одного над другим?

Как вы сказали, bind и лямбды не совсем точно нацелены на одну и ту же цель.

Например, для использования и составления алгоритмов STL лямбды являются явными победителями, ИМХО.

Чтобы проиллюстрировать, я помню действительно забавный ответ, здесь, когда переполнение стека, где кто-то просил идеи шестизначных чисел магии (например, 0xDEADBEEF, 0xCAFEBABE, 0xDEADDEAD и т. Д.), И ему сказали, что если бы он был настоящим программистом на C ++, он просто загрузите список английских слов и используйте простой однострочный слой C ++ 🙂

 #include  #include  #include  #include  #include  #include  #include  int main() { using namespace boost::lambda; std::ifstream ifs("wordsEn.txt"); std::remove_copy_if( std::istream_iterator(ifs), std::istream_iterator(), std::ostream_iterator(std::cout, "\n"), bind(&std::string::size, _1) != 8u || bind( static_cast( &std::string::find_first_not_of ), _1, "abcdef", 0u ) != std::string::npos ); } 

Этот fragment в чистом C ++ 98 откройте английский файл слов, сканирует каждое слово и печатайте только те, которые имеют длину 8 с ‘a’, ‘b’, ‘c’, ‘d’, ‘e’ или ‘f’ буквы.

Теперь включите C ++ 0X и lambda:

 #include  #include  #include  #include  #include  int main() { std::ifstream ifs("wordsEn.txt"); std::copy_if( std::istream_iterator(ifs), std::istream_iterator(), std::ostream_iterator(std::cout, "\n"), [](const std::string& s) { return (s.size() == 8 && s.find_first_not_of("abcdef") == std::string::npos); } ); } 

Это все еще немного тяжело читать (в основном из-за бизнеса istream_iterator), но намного проще, чем версия bind 🙂

C ++ 0x lambdas monoморфны, а связывание может быть полиморфным. Вы не можете иметь что-то вроде

 auto f = [](auto a, auto b) { cout << a << ' ' << b; } f("test", 1.2f); 

a и b должны иметь известные типы. С другой стороны, tr1 / boost / phoenix / lambda bind позволяет вам сделать это:

 struct foo { typedef void result_type; template < typename A, typename B > void operator()(A a, B b) { cout << a << ' ' << b; } }; auto f = bind(foo(), _1, _2); f("test", 1.2f); // will print "test 1.2" 

Обратите внимание, что типы A и B здесь не фиксированы. Только когда f фактически используется, эти два будут выведены.

Синтаксис C ++ 0x lamdba более читабельен, чем синтаксис связывания. После того, как вы переходите к связыванию более 2-3 уровней, код становится практически нечитаемым и его трудно поддерживать. Я бы предпочел более интуитивный синтаксис lambda.

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

При связывании вы вынуждены создавать новую функцию / метод / функтор, даже если логика нужна только в этом месте. Вам нужно придумать соответствующее имя, и это может сделать код менее понятным, поскольку он потенциально может привести к раздельной логике.

С лямбдой вы можете добавить новую логику внутри лямбды (но не вынуждены, если имеет смысл создать новый вызываемый).

Я думаю, что это скорее вопрос вкуса. Люди, которые быстро овладевают новыми технологиями или знакомы с функциональным программированием, вероятно, предпочтут lambda-синтаксис, в то время как более консервативные программисты окончательно предпочтут связывание, так как он больше соответствует традиционному синтаксису C ++.

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

Однако это не меняет того факта, что синтаксис lambda намного эффективнее и чище.

C ++ 0x lambdas существенно заменяет bind. Нет ничего, что вы могли бы связать, чтобы вы не могли воссоздать тривиальный оберточный lambda для достижения того же. std :: tr1 :: bind будет идти по пути std :: bind1st и т. д., когда поддержка lambda широко распространена. Это хорошо, потому что по какой-то причине большинству программистов приходится сталкиваться с трудностями.

  • Объединение двух списков в Haskell
  • Назначение третьего аргумента функции «уменьшить» в функциональном программировании Java 8
  • Обработка инкрементного моделирования данных Изменения в функциональном программировании
  • std :: bind перегрузка
  • Зачем избегать подтипов?
  • Какую задачу лучше всего выполнять в стиле функционального программирования?
  • Функциональное программирование на Java
  • Группировать путем подсчета в Java 8 stream API
  • Использует функцию Haskell id
  • Переполнение стека из глубокой рекурсии в Java?
  • В чем разница между lapply и do.call?
  • Interesting Posts

    Что делает макрос Q_OBJECT? Почему все объекты Qt нуждаются в этом макросе?

    Как настроить тип файла для синтаксических ассоциаций в Sublime Text?

    Может ли панель предварительного просмотра Windows 7 Explorer не блокировать редактирование документов Acrobat и Word?

    В чем разница между M2_HOME и MAVEN_HOME

    Что представляет собой значок Windows 8 в качестве значка прямоугольника в строке заголовка?

    Пользовательская маршрутизация ASP.NET MVC для поиска

    Как получить доступ к частным методам и частным данным через reflection?

    Как написать запрос LDAP для проверки, является ли пользователь членом группы?

    CSS: 100% ширина или высота при сохранении пропорций?

    У моего java-кода есть очевидная ошибка. Почему он компилируется и запускается?

    Как удалить первую строку текстового файла с помощью сценария bash / sed?

    Различия между сериями Intel i7 «M» и «U»

    Как я могу найти количество секунд, прошедших с полуночи с Java?

    Показать прогрессDialog Android

    Посмотреть пейджер в списке?

    Давайте будем гением компьютера.