У меня есть вопрос, о котором предпочтен стиль: станд.:: свяжите По сравнению с лямбдой в 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);
Какой мы должны предпочесть? почему? принятие более сложных ситуаций по сравнению с упомянутым примером. т.е. Каковы преимущества/недостатки одного по другому?
Как вы сказали, связывание и лямбды не совсем точно преследуют одну и ту же цель.
Например, для использования и составления алгоритмов STL, лямбды - явные победители, ИМХО.
Для иллюстрации, я помните действительно забавный ответ, здесь, о переполнении стека, где кто-то спросил идеи шестнадцатеричных магических чисел (например, 0xDEADBEEF, 0xCAFEBABE, 0xDEADDEAD и т. д.) и ему сказали, что если бы он был настоящим программистом на C ++, он бы просто загрузил список Английские слова и используйте простой однострочник C ++ :)
#include <iterator>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
int main()
{
using namespace boost::lambda;
std::ifstream ifs("wordsEn.txt");
std::remove_copy_if(
std::istream_iterator<std::string>(ifs),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"),
bind(&std::string::size, _1) != 8u
||
bind(
static_cast<std::string::size_type (std::string::*)(const char*, std::string::size_type) const>(
&std::string::find_first_not_of
),
_1,
"abcdef",
0u
) != std::string::npos
);
}
Этот фрагмент, на чистом C ++ 98, откройте файл английских слов, просканируйте каждое слово и напечатайте только те, длина которых 8 с 'a', 'буквы b ',' c ',' d ',' e 'или' f.
Теперь включите C ++ 0X и лямбда:
#include <iterator>
#include <string>
#include <algorithm>
#include <iostream>
#include <fstream>
int main()
{
std::ifstream ifs("wordsEn.txt");
std::copy_if(
std::istream_iterator<std::string>(ifs),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"),
[](const std::string& s)
{
return (s.size() == 8 &&
s.find_first_not_of("abcdef") == std::string::npos);
}
);
}
Это все еще немного сложно читать (в основном из-за istream_iterator business), но намного проще, чем версия с привязкой :)
Синтаксис Lamdba C ++ 0x более читабелен, чем синтаксис связывания. Как только вы попадаете на более чем 2-3 уровня привязки, ваш код становится практически нечитаемым и сложным в сопровождении. Я бы предпочел более интуитивный синтаксис лямбда.
Я думаю, это скорее дело вкуса. Люди, которые быстро разбираются в новых технологиях или знакомы с функциональным программированием, вероятно, предпочтут лямбда-синтаксис, в то время как более консервативные программисты определенно предпочтут привязку, поскольку она больше соответствует традиционному синтаксису C ++.
Такое решение должно быть принято в координация с людьми, которые будут работать с кодом, вероятно, посредством большинства голосов.
Однако это не меняет того факта, что лямбда-синтаксис намного мощнее и чище.
Одним из преимуществ лямбда-выражений является то, что они намного полезнее, когда вам нужно добавить немного большой логики поверх существующей функции.
При связывании вы вынуждены создавать новую функцию / метод / функтор, даже если логика когда-либо нужна только в этом месте. Вам нужно придумать подходящее имя, и это может сделать код менее понятным, так как потенциально заставит вас разделить связанную логику.
С помощью лямбда вы можете добавить новую логику внутри лямбда (но не обязаны делать это, если она имеет смысл создать новый вызываемый объект).
C++0x lambdas по сути заменяют связывание. Нет ничего, что можно было бы связать, что нельзя было бы воссоздать тривиальную оберточную лямбду для достижения того же самого. std::tr1::bind пойдет по пути std::bind1st, и т.д., как только поддержка лямбды получит широкое распространение. Что хорошо, потому что по каким-то причинам большинству программистов трудно ориентироваться в связке
.