Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Изменение значения захваченной лямбдой переменной

22.08.2023, 15:53. Показов 1522. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста:


C++
1
2
3
4
5
6
7
8
9
10
int main()
{
    int int_ = 555;
 
    std::function<void()>func;
 
    func = [int_]() { std::cout << int_ << std::endl; };
 
    func();
}
Вот я захватил переменную int_ в лямбду по значению, теперь ведь она хранится где то в памяти функционального объекта "func" ?
Как мне изменить это значение внутри "func" ? Это возможно ?

PS: я знаю, что можно захватить переменную по ссылке, но это получится дублирование переменной, то есть придется держать оригинальную переменную и дополнительно ссылку на нее в самой "func" - это не подходит по использованию памяти.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.08.2023, 15:53
Ответы с готовыми решениями:

Изменение значения статической переменной
не дает =\ static char text; text = &quot;&quot;; это же не конст, а просто статик, в pawn&quot;е часто пользовался static и ок всё...

Изменение значения переменной во время исполнения
Задача: Преобразовать введенный с клавиатуры массив таким образом, чтобы в первой его половине располагались элементы , имевшие нечетный...

Изменение значения переменной через указатель
Дана задача:с помощью указателя увеличить значение переменной b в 3 раза, поменять местами a и c. #include &lt;iostream&gt; using...

29
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.08.2023, 20:27
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от sdf45 Посмотреть сообщение
насколько я понял, ТС не хочет захватывать переменную, но менять хочет, вот я и...
Нет. Он пытается захватить, но хочет невозможного. Я сказал о статическом классе хранения, говоря о объявлениях в пространствах имён (в глобальном, в частности), не зря. Любой оператор видит глобальные переменные. Оператор функции в том числе. тут нет захвата.
0
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
22.08.2023, 20:31
Цитата Сообщение от Optimus11 Посмотреть сообщение
Вот я захватил переменную int_ в лямбду по значению
Цитата Сообщение от Optimus11 Посмотреть сообщение
знаю, что можно захватить переменную по ссылке, но это получится дублирование переменной
Когда вы захватываете по значению - это тоже дублирование.
Но вас это почему то не смущает, а по ссылке смущает.

Цитата Сообщение от Optimus11 Посмотреть сообщение
это не подходит по использованию памяти
Если бы это было действительно так, тогда захват по значению вас бы ещё больше смутил.


Вот так ваше крохоборство выглядит со стороны:

C++
1
2
3
4
5
6
7
8
9
10
void foo(int);
int main()
{
    int v = 0;
 
    foo(v); // О, ужас!!! Здесь будет создана копия аргумента
 
    // Это не подходит по использованию памяти (c) Optimus11
 
}
С таким отношением к жизни, вам подходят только глобальные (или локальные статики) переменные.
При этом вам ни в кое случае нельзя использовать обычные функции.
Ведь они, о боже! будут приводить к дублированию аргументов.

А ещё, вы можете осознать, что ваше крохоборство - это полная чушь, и перестать так заморачиваться.
Если вам нужна лябмда с захватом, просто возьмите, и сделайте её.
Не нужно заниматься пессимизацией.
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
22.08.2023, 20:39  [ТС]
Цитата Сообщение от eva2326 Посмотреть сообщение
Когда вы захватываете по значению - это тоже дублирование.
Но вас это почему то не смущает, а по ссылке смущает.

Если бы это было действительно так, тогда захват по значению вас бы ещё больше смутил.
Подскажите пожалуйста, в каком месте здесь будет дублирование ?


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class my_class_
{
 
public:
 
 
    void user_call_func_1(int user_int)
    {
        list_funcs.push_back([this, user_int]() { this->func_1(user_int); });   //Захват по значению.
    }
 
    //....
 
private:
 
    std::list<std::function<void()>>list_funcs;
 
 
    void func_1(int int_)
    {
        std::cout << int_ << std::endl;
    }
 
};
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
22.08.2023, 20:44
Цитата Сообщение от Optimus11 Посмотреть сообщение
это не подходит по использованию памяти
Че, реально, не подходит? Как ты посчитал?
У меня на x64 gcc std::function с лямдой, у которой даже два объекта по ссылкам захвачено, будет жрать столько же памяти, сколько и с лямдой без захвата (и аллокаций не будет, хранилище 16 байт).
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
22.08.2023, 20:48  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Че, реально, не подходит?
Реально не подходит.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
22.08.2023, 20:57
Цитата Сообщение от Optimus11 Посмотреть сообщение
Реально не подходит.
А конкретнее? Какой у тебя перерасход памяти в приложении из-за захвата по ссылке? (если у тебя всего один захват, то и на твоем компиляторе точно "перерасхода" не будет).
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
22.08.2023, 21:16  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
А конкретнее? Какой у тебя перерасход памяти в приложении из-за захвата по ссылке? (если у тебя всего один захват, то и на твоем компиляторе точно "перерасхода" не будет).
Ну стал бы я парится из одно то захвата ??

Очень кратко и условно:

есть класс "Здания", который в цикле рендера отрисовывает объект здания. У здания есть условно 50-100 параметров:
-Высота
-Ширина
-Вес
-Цвет
-Кол-во окон
-Цвет крыши
....итд итп

По умолчанию все параметры кроме размеров Здания отключены, то есть померенные отвечающие за хранение информации об этих параметрах вообще не должно быть объявлено в классе, так как они будут потреблять место. Ладно если бы нужно было отрисовывать один объект здания - стал бы я парится, но объектов класса зданий может быть хоть 1000 штук, а это уже будет потреблять ощутимое значение памяти.

Так же в класс есть условные API-функцции, если пользователь хочет добавить какой то параметр он вызывает соответствующий метод и устанавливает необходимый параметр:



C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class my_class_Building
{
 
public:
 
 
    void set__user_roof_color(Vector4 color)
    {
        list_funcs.push_back([this, color]() { this->set__roof_color(color); });  //ТО ЕСТЬ параметр захватывается в лямбду и существует в лямбде в единсвенном экземпляре и нигде больше не должен сущестовать, чтобы не занимал больше памяти чем нужно.
    }
 
    void set__user_window_color(Vector4 color)
    {
        list_funcs.push_back([this, color]() { this->set__roof_color(color); });
    }
 
    void set__user_roof_size(Vector2 size)
    {
        list_funcs.push_back([this, size]() { this->set__roof_color(size); });
    }
 
 
 
 
private:
 
    std::list<std::function<void()>>list_funcs;     //Список функий для выполнения
 
 
    //Vector4 color_roof;       //Этих переменных не должно быть в классе, чтобы они не лежали мертвым грузом и не заниимали просто так память, если пользователь не будет их использовать.
    //Vector4 color_window;
    //Vector2 size_roof;
 
 
    void loop_render_start()
    {
        //Отрисовываю и расчитваю ТОЛЬКО те парамтеры, которые устанновил пользовтаель.
        for (auto& f : list_funcs)
            f();
    }
 
 
 
 
 
    void set__roof_color(int int_)
    {
        //код...
    }
 
    void set__user_window_color(int int_)
    {
        //код...
    }
 
    void set__user_roof_size(int int_)
    {
        //код...
    }
 
};
Мой вопрос был в том, как изменить уже захваченную перменную в лямбде - если условному пользователю захчется изменить значение установленного параметра.

Не знаю насколько понятно обьяснил, но как то так.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
22.08.2023, 21:23
Цитата Сообщение от Optimus11 Посмотреть сообщение
Мой вопрос был в том, как изменить уже захваченную перменную в лямбде - если условному пользователю захчется изменить значение установленного параметра.
Так а чего ты это всё не написал в стартовом посте?


Изменить - это удалить старую лямбду и добавить новую.
Для идентификации исользовать unoredered_map, вместо списка, например.
1
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
22.08.2023, 21:26
Цитата Сообщение от Optimus11 Посмотреть сообщение
в каком месте здесь будет дублирование ?
Например, вот здесь:
Цитата Сообщение от Optimus11 Посмотреть сообщение
//Захват по значению.
Причем, при вызове ваших функций тоже создаются дубликаты аргументов.

Даже когда вы просто запускаете лямбду на выполнение:
Цитата Сообщение от Optimus11 Посмотреть сообщение
this->func_1(user_int);
Это тоже приводит к созданию дубликата аргумента, потому что аргумент передается по значению:
Цитата Сообщение от Optimus11 Посмотреть сообщение
void func_1(int int_)

Теперь вы осознаете всю глубину беспощадной реальности?
Вы там пытаетесь какую то одну переменную сэкономить, а оказывается, каждая функция, при каждом вызове, так и норовит создать свою собственную копию.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.08.2023, 21:34
Optimus11, - этот персонаж либо клон Некси99 либо из одной семьи ))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.08.2023, 21:34

Изменение значения переменной через указатель на нее
У меня есть файл main.cpp, в котором хранится int переменная a, которая равна например 10, в другом заголовочном файле, у меня есть...

Изменение значения переменной через заданное время
Всем привет!! Кто знает как можно заделать так что бы значения переменной менялось по заданному времени Например так for...

Странное поведение, если имя локальной переменной лямбды совпадает с захваченной
Добрый день! В процессе решения одной задачи обратил внимание на странное поведение. Приведу упрощённый пример: #include...

Изменение значения переменной, название которой находится в текстовой переменной
Подскажите как мне сделать: у меня есть цикл _0_gray = 1 for i in range(9): peremen = &quot;_&quot; + str(i) + &quot;_gray&quot;\ ...

Изменение значения переменной
доброго времени суток! в поле textarea значение value берется из переменной, соответственно при перезагрузке страницы значение остается...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru