Здравствуйте, Masterkent, Вы писали:
M>nen777w:
I>>>Я раньше думал, что использование лямбды должно упрощать код... Теперь в сомнениях... N>>На самом деле почитав документацию всё становится достаточно понятно
M>Вот только понять, что делает нормальный читабельный код, можно гораздо быстрее. С поиском ошибки — если таковая возникла — аналогично.
I>>>Кроме того, что получилось в коде заюзать лямбду не детским образом, какие-нибудь дополнительные профиты это принесло? N>>Мне просто интересно разобраться было.
M>Вот-вот, из академического интереса побаловаться можно, но чтобы использовать на практике — ну на фиг такое счастье.
N>>Из профитов гм.. например если lambda использовать совместно с <algorithm> это позволит не писать отдельных функторов, делать их сразу по месту.
M>Большое достижение, однако...
единственный профит, что я заметил по сравнению с boost::bind — там placeholers ведут себя иначе.
Можно вместо
std::find_if(... , ... , boost::bind( ...equal?, _1, 100500 ))
писать
std::find_if(... , ... , boost::lambda::_1 == 100500 )
ну и т.п.
Здравствуйте, Ka3a4oK, Вы писали:
KK>Мой совет — не используйте boost::lambda. Это будет сыпать непонятными сообщениями в случае какой-то ошибки и очень долго компилироваться.
Сообщение об ошибках действительно не совсем что бы читаемы. Но всегда можно выделить кусок в котором происходит ошибка и постараться понять почему она происходит.
Потом с опытом ошибок становится намного меньше а со временем исчезают совсем.
KK>Ну и естественно это будет нечитаемо и не неотлаживаемо.
Да нормально всё с этой lambda. Ну да синтаксис сложноват. Но если вникнуть то не так и сложно на самом деле.
Я вокруг неё достаточно долго ходил, синтаксис очень отпугивал, больше предпочитал boost::bind.
Потом вдруг захотелось разобраться, один выходной и все стало значительно понятней.
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, nen777w, Вы писали:
N>>Более сложные приём использования этой офигенной библиотеки, думаю также будут полезны ещё кому-то. __>+1
__>А может просто убедите начальство переходить на GCC 4.5 / VS 2010 а там и нормальные лямбды есть
Что такое "нормальные лямбды"? Имхо, нормальные лямбды — это полиморфные, а не то, что в С++0х, когда надо явно типы прописывать.
On 09.05.2011 20:37, nen777w wrote:
> На самом деле почитав документацию всё становится достаточно понятно, так что > страшных закорючек бояться не стоит. Люди вот например как то же пишут на Perl-е > а там синтаксис по круче будет.
Пишут, запускают, работает, что надо исправить -- пишут снова с нуля,
потому как разобраться уже невозможно. Ты тоже так хочешь ?
Здравствуйте, s.ts, Вы писали:
ST>единственный профит, что я заметил по сравнению с boost::bind — там placeholers ведут себя иначе. ST>Можно вместо ST>std::find_if(... , ... , boost::bind( ...equal?, _1, 100500 )) ST> писать ST>std::find_if(... , ... , boost::lambda::_1 == 100500 ) ST>ну и т.п.
Здравствуйте, jazzer, Вы писали:
J>Что такое "нормальные лямбды"? Имхо, нормальные лямбды — это полиморфные, а не то, что в С++0х, когда надо явно типы прописывать.
IMHO лучше типы прописывать, чем извращаться с boost::lambda
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, jazzer, Вы писали:
J>>Что такое "нормальные лямбды"? Имхо, нормальные лямбды — это полиморфные, а не то, что в С++0х, когда надо явно типы прописывать.
AD>IMHO лучше типы прописывать, чем извращаться с boost::lambda
хмм...
что читабельнее:
std::sort( v.begin(), v.end(), _1 < _2 );
или
std::sort( v.begin(), v.end(), []( Vector::const_reference a, Vector::const_reference b ) { a < b; } );
Или это ты первое называешь извращениями? Имхо, извращение — как раз второе.
И очень жаль, что комитет не смог родить в срок полиморфные лябмды (хоть они, естественно, не спорят с тем, что они нужны).
Еще пример:
auto f = _1 += _2;
int ia, ib;
std::string sa, sb;
f( ia, ib );
f( sa, sb );
сможешь повторить на лябмдах C++0x?
а ведь лябмды именно такого типа нужны для работы с гетерогенными контейнерами типа boost::fusion::vector.
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, s.ts, Вы писали:
ST>>единственный профит, что я заметил по сравнению с boost::bind — там placeholers ведут себя иначе. ST>>Можно вместо ST>>std::find_if(... , ... , boost::bind( ...equal?, _1, 100500 )) ST>> писать ST>>std::find_if(... , ... , boost::lambda::_1 == 100500 ) ST>>ну и т.п.
AD>Нет, это неверно. boost::bind также поддерживает простые операторы сравнения и логические операторы: http://www.boost.org/doc/libs/1_46_1/libs/bind/bind.html#operators
Нет, это верно
Разница в поведении placeholders.
В boost::bind простые операторы не определены для placeholders.
Т.е. нельзя написать _1 == 1, но можно писать что-то типа boost::bind(&C::f, _1) == _2
А в лямбде именно для placeholders определены элементарные операторы.
Вот минимальный код:
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <vector>
#include <algorithm>
void f() {
std::vector<int> v;
std::find_if(v.begin(), v.end(), boost::lambda::_1 == 3 ); // тут все Ok
std::find_if(v.begin(), v.end(), _1 == 3 ); // тут ошибка компиляции error: no match for ‘operator==’ in ‘<unnamed>::_1 == 3’
}
Здравствуйте, jazzer, Вы писали:
J>что читабельнее: J>
J>std::sort( v.begin(), v.end(), _1 < _2 );
J>
J>или J>
J>std::sort( v.begin(), v.end(), []( Vector::const_reference a, Vector::const_reference b ) { a < b; } );
J>
J>Или это ты первое называешь извращениями? Имхо, извращение — как раз второе. J>И очень жаль, что комитет не смог родить в срок полиморфные лябмды (хоть они, естественно, не спорят с тем, что они нужны).
Первый читабельнее. Но это очень простой вариант, поэтому он выглядит более выигрышным. Но если потребуется что-то посложнее простого сравнения, то безымянные ф-ции С++0х уже начинают рулить.
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, jazzer, Вы писали:
J>>что читабельнее: J>>
J>>std::sort( v.begin(), v.end(), _1 < _2 );
J>>
J>>или J>>
J>>std::sort( v.begin(), v.end(), []( Vector::const_reference a, Vector::const_reference b ) { return a < b; } );
J>>
J>>Или это ты первое называешь извращениями? Имхо, извращение — как раз второе. J>>И очень жаль, что комитет не смог родить в срок полиморфные лябмды (хоть они, естественно, не спорят с тем, что они нужны).
AD>Первый читабельнее. Но это очень простой вариант, поэтому он выглядит более выигрышным. Но если потребуется что-то посложнее простого сравнения, то безымянные ф-ции С++0х уже начинают рулить.
Он и является выигрышным. Нужны полиморфные лямбды, встроенные в язык, тогда все будет супер.
И тот же пример будет выглядеть так (как вариант):
std::sort( v.begin(), v.end(), []( auto a, auto b ) { return a < b; } );
можно и другие варианты придумать:
std::sort( v.begin(), v.end(), [auto T]( T a, T b ) { return a < b; } );
Потом драконовское ограничение на выведение возвращаемого типа тоже мне не совсем понятно
Т.е. в примере выше он выведется, а в чуть переделанном — уже нет, потому что тело не записано в форме return expression:
std::sort( v.begin(), v.end(), []( Vector::const_reference a, Vector::const_reference b )
{ bool ret = a < b; return ret; } );
Зачем такое ограничение — хз.
В общем, не о чем спорить, имхо. Фича в С++0х отсутствует, и все это признают, в самом предложении написано, что эти лямбды — monomorphic, и есть соображения о создании полиморфных лямбд, которые как-то (не помню уже, как) конфликтовали c концептами (которые не вошли все равно).
Так что единственный вариант (кроме ручного кодирования) на сегодняшний день для полиморфного функтора — это Boost.Lambda (ну или грядущий Boost.Phoenix).
Здравствуйте, jazzer, Вы писали:
AD>>Первый читабельнее. Но это очень простой вариант, поэтому он выглядит более выигрышным. Но если потребуется что-то посложнее простого сравнения, то безымянные ф-ции С++0х уже начинают рулить.
J>Он и является выигрышным. Нужны полиморфные лямбды, встроенные в язык, тогда все будет супер.
Вообще-то эти вещи друг-другу не мешают, неплохо бы и частичное применение как в первом варианте
(или лучше с поддержкой компилятора: _ < _) и нормальные лямбды.
Здравствуйте, jazzer, Вы писали:
J>Так что единственный вариант (кроме ручного кодирования) на сегодняшний день для полиморфного функтора — это Boost.Lambda (ну или грядущий Boost.Phoenix).
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, jazzer, Вы писали:
J>>Так что единственный вариант (кроме ручного кодирования) на сегодняшний день для полиморфного функтора — это Boost.Lambda (ну или грядущий Boost.Phoenix).
__>Когда уже выйдет этот Boost.Phoenix ? Все ждем..
Да вроде планировали на след. неделе слепить boost 1.47.0, там он уже будет...
А пока можно полюбоваться на то, как с ним работать, см. презентацию с BoostCon'11 в соседнем форуме
Proto рулит
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, _nn_, Вы писали:
__>>Здравствуйте, jazzer, Вы писали:
J>>>Так что единственный вариант (кроме ручного кодирования) на сегодняшний день для полиморфного функтора — это Boost.Lambda (ну или грядущий Boost.Phoenix).
__>>Когда уже выйдет этот Boost.Phoenix ? Все ждем..
J>Да вроде планировали на след. неделе слепить boost 1.47.0, там он уже будет...
О как.
Ждем.
Т.е. Boost.Lambda, Boost.Bind скоро можно будет выкинуть ?
J>А пока можно полюбоваться на то, как с ним работать, см. презентацию с BoostCon'11 в соседнем форуме J>Proto рулит
<offtop>Лучше бы уже С++ улучшили, чтобы не делать такие извращения.</offtop>
Здравствуйте, _nn_, Вы писали:
__>Т.е. Boost.Lambda, Boost.Bind скоро можно будет выкинуть ?
Вроде как. У лямбды своих чисто технических проблем хватает, и я надеюсь, что Феникс их решит. Вроде как все к тому шло.
J>>А пока можно полюбоваться на то, как с ним работать, см. презентацию с BoostCon'11 в соседнем форуме J>>Proto рулит
__><offtop>Лучше бы уже С++ улучшили, чтобы не делать такие извращения.</offtop>
Ну чтоб улучшить С++ до такого уровня, чтоб Прото с Фениксом стал не нужен — это реолючия целая, сравнимая с концепцтами по масштабам.
Хотя я бы не отказался, конечно