Название: сократить написание типа лямбды Отправлено: kambala от Июль 02, 2014, 20:45 Здравствуйте. Есть такой код (сокращенный, не относящиеся к делу части убраны):
Код Можно ли как-то покороче описать лямбды (не писать их огромный тип)? traverseGrid может быть и методом, не суть важно. Название: Re: сократить написание типа лямбды Отправлено: Bepec от Июль 02, 2014, 21:17 define не подойдёт?
Или ещё что то надо? Название: Re: сократить написание типа лямбды Отправлено: kambala от Июль 02, 2014, 21:30 ну хотелось бы typedef например, дефайны мне не надо
Название: Re: сократить написание типа лямбды Отправлено: Igors от Июль 03, 2014, 08:37 Хотелось бы узнать чем вызван такой синтаксис, что он дает, какую общность Вы хотели получить. По коду это не очень ясно, подробности бы не помешали
Спасибо Название: Re: сократить написание типа лямбды Отправлено: navrocky от Июль 03, 2014, 09:02 Хотелось бы узнать чем вызван такой синтаксис, что он дает, какую общность Вы хотели получить. По коду это не очень ясно, подробности бы не помешали Спасибо Ну я думаю, имелось ввиду сократить запись лямбды, поиск способа. Для примера лямбда на C#: Код: traverseGrid(_leftNumberGrid, (numberGrid, m, a) => { return numberGrid.cellAt(m, a); }); и еще раз оригинал: Код: traverseGrid(_leftNumberGrid, [](const NumberGrid &numberGrid, uchar m, uchar a) { return numberGrid.cellAt(m, a); }); К сожалению, тут даже typedef-ить нечего, типы параметров однословные. Разве что typedef const NumberGrid& NumberGridConstRef;. Но это не помогает сокращатить код в данном случае. Название: Re: сократить написание типа лямбды Отправлено: m_ax от Июль 03, 2014, 10:06 Здравствуйте. Есть такой код (сокращенный, не относящиеся к делу части убраны): Код Можно ли как-то покороче описать лямбды (не писать их огромный тип)? traverseGrid может быть и методом, не суть важно. А чем мотивировано то, что traverseGrid должна быть именно лямбдой? Можно например проще: Код
Название: Re: сократить написание типа лямбды Отправлено: kambala от Июль 03, 2014, 12:39 Хотелось бы узнать чем вызван такой синтаксис, что он дает, какую общность Вы хотели получить. По коду это не очень ясно, подробности бы не помешали в теле traverseGrid выполняется двойной цикл (обход сетки :) ), тело цикла которого для двух объектов отличается лишь способом получения ячейки по индексам. сейчас подумалось, что может стоит перегрузить cellAt, чтобы не заниматься подобными вещами.Спасибо Цитировать А чем мотивировано то, что traverseGrid должна быть именно лямбдой? пока что написал как лямбду чтобы метод на «один чих» не создавать. в будущем скорее всего появятся еще объекты, для которых надо будет выполнять traverseGrid в подклассе.вообще вопрос был не о traverseGrid, а о длинном типе [](const NumberGrid &numberGrid, uchar m, uchar a) :) Пусть, например, есть 10 объектов, для которых надо написать подобную лямбду, неужели надо каждый раз этот длинный тип пропихивать (без дефайнов)? По сути он же повторяет тип из std::function в traverseGrid, может можно это как-то унифицировать? Название: Re: сократить написание типа лямбды Отправлено: m_ax от Июль 03, 2014, 13:54 Если все лямбды подобны (т.е. вызывается один и тот же метод cellAt) то почему не унифицировать так:
Код
Или суть в том, что сигнатура лямбды одинакова, но реализация может сильно отличаться от случая к случаю? Название: Re: сократить написание типа лямбды Отправлено: kambala от Июль 03, 2014, 14:17 Или суть в том, что сигнатура лямбды одинакова, но реализация может сильно отличаться от случая к случаю? изначально был именно такой вопрос. но в данном конкретном случае будет достаточно и ссылки на cellAt. спасибо за подсказку!Цитировать сейчас подумалось, что может стоит перегрузить cellAt, чтобы не заниматься подобными вещами. так не получится, в другом месте код станет нелогичнымНазвание: Re: сократить написание типа лямбды Отправлено: kambala от Июль 03, 2014, 14:48 что-то не хочет компилиться:
Код
Цитировать /Users/kambala/Documents/Projects/iOS/relaks/Relaks/classes/model/puzzles/Nonogram.cpp:70:87: error: no viable conversion from '<overloaded function type>' to 'std::function<const NumberCell &(const NumberGrid &, uchar, uchar)>' std::function<const NumberCell &(const NumberGrid &numberGrid, uchar m, uchar a)> x = &NumberGrid::cellAt; ^ ~~~~~~~~~~~~~~~~~~~ In file included from /Users/kambala/Documents/Projects/iOS/relaks/Relaks/classes/model/puzzles/Nonogram.cpp:9: In file included from /Users/kambala/Documents/Projects/iOS/relaks/Relaks/classes/model/puzzles/Nonogram.h:12: In file included from /Users/kambala/Documents/Projects/iOS/relaks/Relaks/classes/model/puzzles/Puzzle.hpp:15: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/fstream:169: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ostream:131: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ios:216: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__locale:18: In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/mutex:177: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1448:5: note: candidate constructor not viable: no overload of 'cellAt' matching 'nullptr_t' for 1st argument function(nullptr_t) _NOEXCEPT : __f_(0) {} ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1449:5: note: candidate constructor not viable: no overload of 'cellAt' matching 'const std::__1::function<const NumberCell &(const NumberGrid &, unsigned char, unsigned char)> &' for 1st argument function(const function&); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1450:5: note: candidate constructor not viable: no overload of 'cellAt' matching 'std::__1::function<const NumberCell &(const NumberGrid &, unsigned char, unsigned char)> &&' for 1st argument function(function&&) _NOEXCEPT; ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1452:7: note: candidate template ignored: couldn't infer template argument '_Fp' function(_Fp, typename enable_if ^ 1 error generated. Методы объявлены так: Код
Цитировать $ clang -v Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.3.0 Thread model: posix Название: Re: сократить написание типа лямбды Отправлено: m_ax от Июль 03, 2014, 16:18 Правильно будет так:
Код
Но проблема ещё и в том, что метод cellAt - перегруженный.. Не знаю как в такой ситуации std::function заставить работать.. Название: Re: сократить написание типа лямбды Отправлено: kambala от Июль 03, 2014, 17:25 без имен параметров тоже пробовал, ошибка была та же. пробовал даже
Код все равно ошибка, только другая. придется создать еще один метод, который будет сам вызывать cellAt с нужным порядком параметров (объекты-сетки на самом деле типов, производных от NumberGrid). значит, ответом на исходный вопрос будет «невозможно, сигнатуру лямбды надо всегда писать»? Название: Re: сократить написание типа лямбды Отправлено: m_ax от Июль 03, 2014, 17:51 значит, ответом на исходный вопрос будет «невозможно, сигнатуру лямбды надо всегда писать»? Нет, "невозможно" здесь слишком громкое слово.. Например, если посмотреть в boost::phoenix то там вообще вместо лямбды можно писать сами выражения (без всяких сигнатур функций) например можно как то так (отрывок из одного проекта): Код
Думаю, здесь можно и как-нить более изящнее решить проблему.. Название: Re: сократить написание типа лямбды Отправлено: m_ax от Июль 03, 2014, 22:06 Вобщем у меня заработало так:
Код
Название: Re: сократить написание типа лямбды Отправлено: kambala от Июль 03, 2014, 22:51 от старых добрых указателей никуда не деться :)
в общем, я traverseGrid превратил в шаблонный метод, чтобы он любые сетки принимал, и пришлось добавить парочку методов в базовый класс сетки чтобы вышло коротко и красиво. |