Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
че-то я не допер.. как сделать так, чтобы она заработала? вот тестовый код Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. а вот ошибки Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. выходит что у лямбды нет конструктора копирования, а у std::function - есть, и он пытается собраться, но это разумеется не получается. но компилятор показывает ошибку в другом месте - в том, где все нормально. если закоментировать создание std::function то код прекрасно компилится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2016, 22:52 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_black, Внутри лямбда хранит захваченные значения в виде полей класса. std::function внутри хранит саму лямбду. Условно: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Для того чтобы сохранить лямбду в свое внутреннее поле function копирует ее. При этом рекурсивно копируются и ее поля. Поэтому если в лямбде хранится захваченное значение для которого копирование отключено, то вся эта конструкция не скомпилируется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 00:26 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Т.е. другими словами у этой конкретной лямбды нет конструктора копирования, потому что его нет у захваченного выражения. А вообще у лямбд конечно есть к-тор копирования ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 00:28 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
http://stackoverflow.com/questions/20843271/passing-a-non-copyable-closure-object-to-stdfunction-parameter оказалось я не первый кто об это вспоткнулся :) я так понял, что у лямбды пропадает конструктор копирования если у одного из замыканий его нет (как указал Anatoly Moskovsky) а вот std::function - у неё есть конструктор копирования, и его не отключают если объект не копируемый.. короче либо писать свою noncopyable_function либо использовать что-нибудь из ответов.. я подумал что эту проблему можно решить написав свою функцию и ипспользовать std::is_copy_constructible и std::is_copy_assignable , но похоже так нельзя сделать - это будут разные классы, и какой-нибдуь std::vector<my_super_function<void()>> не сможет держать и копируемые и некопируемые функторы.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 10:48 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_black, Вообще перемещение в лямбды выглядит сомнительным по безопасности, если вы их потом пытаетесь копировать эту лямбду в несколько других лямбд. Валидной останется только одна копия, а остальные будут видеть пустой объект. Используйте shared_ptr вместо стекового объекта, который вы захватываете перемещением. Это решит и проблему с компиляцией и можно будет создавать сколько угодно равноценных копий лямбды. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 14:46 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyalexy_black, Вообще перемещение в лямбды выглядит сомнительным по безопасности, если вы их потом пытаетесь копировать эту лямбду в несколько других лямбд. Валидной останется только одна копия, а остальные будут видеть пустой объект. Используйте shared_ptr вместо стекового объекта, который вы захватываете перемещением. Это решит и проблему с компиляцией и можно будет создавать сколько угодно равноценных копий лямбды.лямбду в лямбду копировать? это зачем и как? да, shared_ptr - выход. но не хочется для этого выделять память. это нужно системный вызов делать.. там есть такой предложение: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. только там в конструкторе копирования исключение, а я асерт сделал - так удобнее (когда в дебаге прога свалится, узнать где). если код можно протестить хорошо - все варианты использования - то все гуд. если нельзя так протестить то наверное лучше сделать с shared_ptr . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 15:13 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_blackлямбду в лямбду копировать? это зачем и как? В function. alexy_blackда, shared_ptr - выход. но не хочется для этого выделять память. это нужно системный вызов делать Не нужно. Вы путаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 15:42 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, shared_ptr выделяет память, там оператор new - malloc (правда я реализацию смотрел, но по-другому как?) . создание переменной в куче более дорого чем на стеке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 17:59 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_black, malloc - это не системный вызов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 18:57 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskymalloc - это не системный вызов. http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html posix однако.. вобще выделяет память система. то есть её "просят" выделить память, а потом, когда это область больше не нужна её возращают. память должна выделять система - она контролирует чтобы опреративки хватило.. а напрямую нельзя обращаться к памяти - то есть опять же система должна помнить где она этот кусок предоставила. стек же обычно выделяется один раз - большой кусок, а потом этим куском пользуются. потом он может быть расширен, тоже вроде системным вызовом, но это все равно будет всего один вызов в исключительной ситуации, а не вызов на каждую перменную на стеке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 19:33 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Глубоко не вникал в казуистику перемещений, поэтому есть непонятный момент как может быть перемещен локальный объект. Как это реализует компилятор? Если по простому то перемещение на уровне асма это смена указателей, т.е. данные объекта на том же месте остаются. Но как они могу остаться на том же месте если это локальная переменная на стэке? При выходе из функции стэк освободился, но "свободный" кусочек остался занят перемещенной переменной? Ерунда какая-то ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 19:42 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Dima T, Об этом речь? https://en.wikipedia.org/wiki/Return_value_optimization А это добавка к фокусам компилятора https://en.wikipedia.org/wiki/Call_stack#STACK-UNWINDING ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 19:48 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_blackAnatoly Moskovskymalloc - это не системный вызов. http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html posix однако.. Тут нигде не сказано что malloc это системный вызов. Вы путаете рантайм С и системные вызовы. Стандартная функция рантайма С malloc выделяет память из кучи (заранее выделенной у системы области памяти процесса). Когда куча заканчивается, malloc выделяет у системы следующий участок кучи (обычно через системный вызов mmap или его аналог в других ОС). Для больших размеров объектов, malloc может сразу у системы память вызывать. Но это надо большие массивы выделять. А у вас естественно через кучу выделяется, поэтому никакие системные вызовы не замедляют работу, т.к. вызываются слишком редко. При этом я не спорю с тем что динамическое создание объекта чуть медленнее чем стековое. Но не настолько, чтобы городить вот эти костыли с фейковыми конструкторами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 19:49 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
SiemarglDima T, Об этом речь? https://en.wikipedia.org/wiki/Return_value_optimization А это добавка к фокусам компилятора https://en.wikipedia.org/wiki/Call_stack#STACK-UNWINDING Не об этом. Вот у alexy_black код 18996721 Код: plaintext 1. 2. 3. 4. где tasks_ свойство класса, а tasks локальная переменная, т.е. область видимости совсем другая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 20:03 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
alexy_blackAnatoly Moskovskymalloc - это не системный вызов. http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html posix однако.. вобще выделяет память система. то есть её "просят" выделить память, а потом, когда это область больше не нужна её возращают. память должна выделять система - она контро. Ты линк на malloc дал неправильный ВОТ правильный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 20:08 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Dima T, Видимо захват лямбдой this дает нужную область видимости. А потом _внутри_ листа подменяются указатели. По поводу копирования - есть еще такое https://en.wikipedia.org/wiki/Copy_elision Только мне кажется, что так писать код не очень хорошо, как написал Алексей - он и сам то не разберется =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 20:49 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
SiemarglDima T, Видимо захват лямбдой this дает нужную область видимости. А потом _внутри_ листа подменяются указатели. По поводу копирования - есть еще такое https://en.wikipedia.org/wiki/Copy_elision Только мне кажется, что так писать код не очень хорошо, как написал Алексей - он и сам то не разберется =) Написано как раз понятно, просто и очевидно, но как оно в итоге будет реализовано компилятором - непонятно. ИМХУ Надо просто затестить производительность, только надо придумать как тестить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2016, 21:06 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Dima TГлубоко не вникал в казуистику перемещений, поэтому есть непонятный момент как может быть перемещен локальный объект. Как это реализует компилятор? Если по простому то перемещение на уровне асма это смена указателей, т.е. данные объекта на том же месте остаются. Но как они могу остаться на том же месте если это локальная переменная на стэке? При выходе из функции стэк освободился, но "свободный" кусочек остался занят перемещенной переменной? Ерунда какая-то Во-первых класс должен поддерживать перемещение и сам его реализовывать (когда возможно, компилятор генерирует этот код). Во-вторых, обычно перемещение реализуется как рекурсивный swap всех полей класса. Т.е. сам объект остается, а его содержимое меняется местами с содержимым конечного объекта. Так что неважно где расположены объекты. Такая оптимизация конечно имеет смысл, только для классов с полями указывающими на динамическую память, и имеет цель избежать при копировании выделения и копирования памяти. Например хорошие кандидаты - std::vector, std::string. Плохие кандидаты: std::array, std::tuple - так как вся память находится в самом объекте, и повторное создание с нуля через стандартный к-тор копирования будет в 2 раза быстрее перемещения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.04.2016, 03:05 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
Dima Tкак оно в итоге будет реализовано компилятором - непонятно. ИМХУ Надо просто затестить производительность, только надо придумать как тестить. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. вот так что ли? тут все понятно и на глаз :) вектор кстати оказался гараздо быстрее (в строке using можно менять vector -> list ... ), что и понятно, ведь это просто массив, а list - это структуры, которые еще и на соседей указатели держат. но во обоих случаях время на свап было мнгновенным, а на copy огромным (на вектор я еще пару нулей добавил, а вот лист такого не выдержал - израсходовал все память и был killed) . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.04.2016, 18:24 |
|
||
|
создание std::function<> из лямбды с захваченной moveableonly переменной
|
|||
|---|---|---|---|
|
#18+
по поводу перемещения: не думаю что есть смысл поды перемещать.. то етсь они навеное в любом случаи копируются. а вот если класс содержит указатели или какие-нибудь дескрипторы и тому подобное, то задача пермещения - просто оставить объект в таком состоянии, чтобы он мог уничтожится без проблем. где-то прочитал: "семантика перемещения - это просто способ сказать, что объект нам больше не нужен". имхо очень доступное объяснение. то есть если вызван констрктор или опрератор перемещения, то это значит, что другой объект будет уничтожен сразу после того как функция отработает и нигде не будет использоваться. а как этим воспользоваться решает программист. если он там сделает такой же конструктор как и констурктор копирования, то ничего не изменится по сравнения с копированием. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.04.2016, 18:31 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39206689&tid=2018563]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
26ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
| others: | 12ms |
| total: | 118ms |

| 0 / 0 |
