Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Renji
1901 / 1299 / 291
Регистрация: 05.06.2014
Сообщений: 3,719
#1

Лямбды и захват переменных - C++

29.10.2015, 15:54. Просмотров 554. Ответов 10
Метки нет (Все метки)

Лямбды могут захватывать переменные через [value1,value2]{}. Вопрос: а куда, собственно, эти переменные захватываются - в статический буфер общий для всех вызовов лямбды или в локальный буфер формируемый под каждый вызов и передающийся лямбде на манер this?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.10.2015, 15:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Лямбды и захват переменных (C++):

Захват звука - C++
Надо захватить звук в буфер для анализа. Ёмкость буфера искуственно ограничить и хранить в нём только последние n секунд. При поступлении...

Захват видео с веб-камеры (C++) - C++
Здравствуйте! Я установил Visual Studio 2015 Community и библиотеку OpenCV 3.1.0 на Windows 10. Потом я написал программу, которая...

Захват информации графического приложения - C++
Каким образом можно захватить информацию(текст) с графического приложения для дальнейшего копирования на диск, как это действие ...

Можно ли на c++ создать программу подобную camstudio (захват видео с экрана)? - C++
Каким образом записывает видео с экрана?Можно ли на c++ сделать что то такое? И что нужно знать чтобы сделать что то подобное помогите

Захват изображения с одного монитора и копирование его на второй, подключенные к одному и тому же компьютеру - C++
Друзья, подскажите пожалуйста. Имеется два монитора, подключенных к одному компьютеру. Нужно реализовать захват экрана одного монитора, для...

Захват звука - C++ Builder
Необходимо захватить звук на компьютере, неважно что это будет музыка или звук открытие папки.... и вывести его как зрительный образ на...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
29.10.2015, 16:01 #2
Лямбда это по сути сахар для создания функтора, поэтому логично предположить, что это будут некие данные-члены автоматически сгенеренного объекта функтора.
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
29.10.2015, 16:01 #3
Там же есть указатели - по ссылке или по значению брать (= и &).
Renji
1901 / 1299 / 291
Регистрация: 05.06.2014
Сообщений: 3,719
29.10.2015, 16:15  [ТС] #4
Цитата Сообщение от Tulosba Посмотреть сообщение
Лямбда это по сути сахар для создания функтора, поэтому логично предположить, что это будут некие данные-члены автоматически сгенеренного объекта функтора.
Проблема в том, что std::function ничего про эти захваченные переменные не знает, а значит данных-членов под захват там нет. Вот я и не пойму куда же тогда эти захваченные переменные деваются.
Цитата Сообщение от nmcf Посмотреть сообщение
Там же есть указатели - по ссылке или по значению брать (= и &).
Ссылка тоже требует памяти под свое хранение. Если, конечно, адрес объекта на который ведет ссылка не известен на стадии компиляции (а он известен только для static переменных).
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
29.10.2015, 16:28 #5
Пример для иллюстрации:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
void print(int i) {
    std::cout << i << std::endl;
}
 
struct F {
    F(int i): i_(i) {}
    void operator()() const { print(i_); }
private:
    int i_;
};
 
int main() {
    
    int v = 42;
 
    auto l = [v]{ print(v); };
    l();
    
    auto f = F(v);
    f();
}
По сути, l есть альтернативный способ достичь того же, что делает f.

Т.е. при захвате по значение у тебя будет сгенерирован член-данных с типом значения, при захвате по ссылке - член-данных с типом ссылки.
Renji
1901 / 1299 / 291
Регистрация: 05.06.2014
Сообщений: 3,719
29.10.2015, 16:31  [ТС] #6
Цитата Сообщение от Tulosba Посмотреть сообщение
Т.е. при захвате по значение у тебя будет сгенерирован член-данных с типом значения, при захвате по ссылке - член-данных с типом ссылки.
Ок, скажем по другому. Откуда в этом примере std::function<void()> знает что надо сформировать член данных с ссылкой?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
#include<functional>
using namespace std;
int main()
{
    int x=0;
    //в объявлении test ни слова о необходимости хранить ссылку на x
    std::function<void()>test=[&x]{x+=1;};
    //и тем не менее, эта строчка увеличит x на единицу
    test();
    std::cout<<x;
    return 0;
}
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
29.10.2015, 16:39 #7
Ровно оттуда же, откуда и при явном использовании функтора:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<functional>
using namespace std;
 
struct F {
    F(int& i): i_(i) {}
    void operator()() const { i_+=1; }
private:
    int& i_;
};
 
int main()
{
    int x=0;
    //в объявлении test ни слова о необходимости хранить ссылку на x
    //std::function<void()>test=[&x]{x+=1;};
    F test(x);
    //и тем не менее, эта строчка увеличит x на единицу
    test();
    std::cout<<x;
    return 0;
}
Или теперь мы уже про std::function, а не про лямбду?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
29.10.2015, 17:27 #8
Renji, std::function такой объект.
http://en.cppreference.com/w/cpp/uti...ction/function
Принимает любой callable тип и просто хранит его объект.
Renji
1901 / 1299 / 291
Регистрация: 05.06.2014
Сообщений: 3,719
29.10.2015, 17:30  [ТС] #9
Цитата Сообщение от Tulosba Посмотреть сообщение
Или теперь мы уже про std::function, а не про лямбду?
Мне казалось что раз std::function может быть инициализирован обычной функций, он является просто оберткой вокруг указателя на функцию. А раз он кушает еще и лямбды, значит лямбде должно хватать этого указателя. Посмотрел на sizeof от std::function - понял что ошибся, оно сильно тяжелее указателя.
xEmpire
24 / 24 / 9
Регистрация: 07.12.2012
Сообщений: 169
Завершенные тесты: 1
29.10.2015, 18:07 #10
Renji, std:function может хранить как функцию так и функциональный объект с одинаковой сигнатурой. А лямбда - это безымянный функциональный объект (функтор).
hoggy
6534 / 2714 / 469
Регистрация: 15.11.2014
Сообщений: 5,993
Завершенные тесты: 1
29.10.2015, 20:53 #11
Цитата Сообщение от Renji Посмотреть сообщение
Лямбды могут захватывать переменные через [value1,value2]{}. Вопрос: а куда, собственно, эти переменные захватываются - в статический буфер общий для всех вызовов лямбды или в локальный буфер формируемый под каждый вызов и передающийся лямбде на манер this?
лямбда - это обычный класс-функтор.
если лямбда хапанула контекст,
то компилятор сгенерирует функтор с данными-членами.
которые и будут хранить этот контекст.

итого:
никакой разницы между лямбдой,
и как если бы вы сами вручную этот функтор приготовили.

просто удобнее.

Цитата Сообщение от Renji Посмотреть сообщение
Проблема в том, что std::function ничего про эти захваченные переменные не знает
std::function - это всего лишь тонкая обертка над функторами.
ей без разницы на что нацеливаться.
главное, что бы оно могло вызваться согласно протоколу
(типу функции указанному в параметре шаблона)

поэтому, она не заморачивается тем, что под капотом функтора.
просто дергает его оператор()
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.10.2015, 20:53
Привет! Вот еще темы с ответами:

Захват изображения со второго монитора - C++ Builder
Как захватить изображение со ВТОРОГО монитора в системе? Код ниже захватывает изображение всегда с первого hDC = GetDC (0); ...

Захват const переменной из лямбды: разный результат в g++ и clang - C++
Добрый день. #include &lt;iostream&gt; template &lt;class T&gt; void foo(const T&amp; t) { const int a = t; { ...

лямбды - Python
Необходимо определить функции так, чтобы проходили доктесты. Используй лямбды, а не вложенные функции. Каждое решение должно состоять из...

Лямбды - C++
Непонятно, как работает это простенький код, и почему именно так: int id = 0; auto f = () mutable { cout &lt;&lt; &quot;id: &quot; &lt;&lt; id &lt;&lt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
29.10.2015, 20:53
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru