Может, неправильно выразился, но суть такая: есть необходимость использовать callback'и, функторы для этого хорошо подходят. Но хочется иметь возможность передавать туда и лямбды с непустыми []. Специфика такова, что нет ни std::function, ни тем более boost'а.
R>а пример того чего хочется но не компилится — можно ? а то не понятно
Хм. Сейчас даже не и не скажу. Это моя первая лямбда
Колега возится, у него жирный шаблон инстанциируется, он изобретает какую-то либу колбеков, чтобы уменьшить размер результирующего кода — шутка ли сказать — каждое инстанциирование по 1Кб кода добавляет
Я погуглил, нашел какое-то обсуждение (сейчас уж не найду, завтра уточню), там лямбду прокидывали через указатель на функцию, я решил, что это наверно то, что мне нужно. Начал разбираться — лябда посложнее пустой не компилится, в коментах пишут, что нужен std::function.
Вот, как-то так
Сорри, если сумбурно, только начал грызть 11 стандарт
Думал, сами догадаетесь, в чем проблема, а то я пока не осознал
ЗЫ Хотя, я сделал нечто похожее на то, что у коллеги, только без колбеков внутри, мой класс получился нешаблонным, сверху навернул шаблон на пять строчек, добавил туда колбек шаблонным параметром, который любые лямбды кушает так же как и функторы, и теперь думаю, что коллега что-то не совсем то хочет сделать
Здравствуйте, Alexander G, Вы писали:
M>>Специфика такова, что нет ни std::function, ни тем более boost'а.
AG>Чем именно вызван отказ от std::function ?
Его нет в компиляторе
AG>Что ещё нельзя? Вариадики, type traits?
Вариадики вроде есть, как работают — не знаю, вроде худо-бедно пашут. type traits —
AG>Дело в том, что навернуть что-то своё можно, но оно не будет лучше std::function, если покрывать самый общий случай.
Ну вот ребята там что-то подобное и пилят уже месяц почти; я, как новый человек в конторе вообще, и незнакомый с C++11 в частности, пока особо в это не лезу. Но как-то за пол-дня прикрутил к коду с аналогичным функционалом лямбду, вот и думаю, что они там пилят, и главное, надо ли
M>Ну вот ребята там что-то подобное и пилят уже месяц почти; я, как новый человек в конторе вообще, и незнакомый с C++11 в частности, пока особо в это не лезу. Но как-то за пол-дня прикрутил к коду с аналогичным функционалом лямбду, вот и думаю, что они там пилят, и главное, надо ли
Здравствуйте, reversecode, Вы писали:
M>>Ну вот ребята там что-то подобное и пилят уже месяц почти; я, как новый человек в конторе вообще, и незнакомый с C++11 в частности, пока особо в это не лезу. Но как-то за пол-дня прикрутил к коду с аналогичным функционалом лямбду, вот и думаю, что они там пилят, и главное, надо ли
R>срочно опубликовать этот щедевр для мема сюда http://govnokod.ru/cpp
Здравствуйте, Marty, Вы писали:
M>Ну вот ребята там что-то подобное и пилят уже месяц почти; я, как новый человек в конторе вообще, и незнакомый с C++11 в частности, пока особо в это не лезу. Но как-то за пол-дня прикрутил к коду с аналогичным функционалом лямбду, вот и думаю, что они там пилят, и главное, надо ли
Ну, надо ли. Случаи разные бывают.
Если не нужен type erasure, можно просто передавать как выводимый шаблонный параметр.
Если не надо поддерживать любые сигнатуры, только для одной, то задача тоже сильно упрощается.
Если лямбду не нужно хранить, а только спускать вниз по стеку, то через указатель на лямбду можно упростить.
Хорошая реализация, такая как в boost::function, помимо обеспечения type erasure, с поддержкой всех сигнатур, и хранением лябмды в себе, делает ещё следующее:
1. Избегает полиморфизма на C++ классах в пользу полиморфизма на указателях на функции. То есть чтобы на все возможные сигнатуры не было пачки RTTI и vtable.
2. Делает small value optimization, то есть, если лямбда небольшая хранит её не на куче, а по значению.
Здравствуйте, Alexander G, Вы писали:
M>>Ну вот ребята там что-то подобное и пилят уже месяц почти; я, как новый человек в конторе вообще, и незнакомый с C++11 в частности, пока особо в это не лезу. Но как-то за пол-дня прикрутил к коду с аналогичным функционалом лямбду, вот и думаю, что они там пилят, и главное, надо ли
AG>Ну, надо ли. Случаи разные бывают. AG>Если не нужен type erasure, можно просто передавать как выводимый шаблонный параметр. AG>Если не надо поддерживать любые сигнатуры, только для одной, то задача тоже сильно упрощается.
Ну вот они как раз и уперлись в поддержку любых сигнатур. Хз, зачем, правда.
AG>Если лямбду не нужно хранить, а только спускать вниз по стеку, то через указатель на лямбду можно упростить.
Тут хз, но, скорее всего, таки нужно хранить
AG>Хорошая реализация, такая как в boost::function, помимо обеспечения type erasure, с поддержкой всех сигнатур, и хранением лябмды в себе, делает ещё следующее: AG>1. Избегает полиморфизма на C++ классах в пользу полиморфизма на указателях на функции. То есть чтобы на все возможные сигнатуры не было пачки RTTI и vtable. AG>2. Делает small value optimization, то есть, если лямбда небольшая хранит её не на куче, а по значению.
Здравствуйте, Marty, Вы писали:
AG>>Хорошая реализация, такая как в boost::function, помимо обеспечения type erasure, с поддержкой всех сигнатур, и хранением лябмды в себе, делает ещё следующее: AG>>1. Избегает полиморфизма на C++ классах в пользу полиморфизма на указателях на функции. То есть чтобы на все возможные сигнатуры не было пачки RTTI и vtable. AG>>2. Делает small value optimization, то есть, если лямбда небольшая хранит её не на куче, а по значению.
M>Кучи нет. Кстати
Размер фиксированного буфера под лямбду задается параметром шаблона, ещё от 2 до 4 указателей уходит на функции вызова, деструктора, копирования и перемещения лямбды.
Однако если нет кучи, то проще все-таки использовать лямбды без захвата состояния, чтобы свести все к указателю на функцию. Вменяемые интерфейсы обычно так и проектируют, закладывают какой-нибудь void* аргументом callback функции:
using callback = void (*)(void* user_data, float x);
void explode(int y, callback cb, void* user_data);
struct world { ... } my;
explode(1000, [](void* data, float x){ auto my = static_cast<world*>(data); ... }, &my);
Здравствуйте, Marty, Вы писали:
AG>>Чем именно вызван отказ от std::function ? M>Его нет в компиляторе
Как такое возможно что лямбды есть в компиляторе а std::function нет???
Да и вообще это же заголовочный файл, его скорее всего можно затащить оттуда где он есть (из другого компилятора, из буста и т.д.)
Нет такого преступления, на которое не пошло бы суверенное родоплеменное быдло ради продления своего бессмысленного рода и распространения своего бессмысленного генома.
Здравствуйте, anonymouse2, Вы писали:
AG>>>Чем именно вызван отказ от std::function ? M>>Его нет в компиляторе
A>Как такое возможно что лямбды есть в компиляторе а std::function нет??? A>Да и вообще это же заголовочный файл, его скорее всего можно затащить оттуда где он есть (из другого компилятора, из буста и т.д.)
Вроде пробовали, не взлетело. Это embedded, детка
А Keil, конкретно, с тех пор как я увидел его в первый раз в 96ом году, ни капельки не изменился Для меня было шоком, что он поддерживает 11 плюсовый стандарт, пусть и с урезанной STL
Здравствуйте, Marty, Вы писали:
M> Здравствуйте!
M>Может, неправильно выразился, но суть такая: есть необходимость использовать callback'и, функторы для этого хорошо подходят. Но хочется иметь возможность передавать туда и лямбды с непустыми []. Специфика такова, что нет ни std::function, ни тем более boost'а.
M>Какие есть варианты? Желательно попроще
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, Alexander G, Вы писали:
M>>>Специфика такова, что нет ни std::function, ни тем более boost'а.
AG>>Чем именно вызван отказ от std::function ?
M>Его нет в компиляторе
Сделай велосипед. Элементарно пишется, если не надо 100500 фич с биндами и прочим.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте