Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/34: Рейтинг темы: голосов - 34, средняя оценка - 4.94
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337

Назначение mutable в лямбда-функции

13.03.2016, 09:26. Показов 7049. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прокомментируйте, чтоб не выдумывать. Спецификатор mutable определяет по списку захвата локальные статические переменные?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    int v1 = 32;
    cout << "v1 = " << v1 << endl << endl;
 
    //----------------------------------------------
    auto f = [v1]()mutable { return ++v1; }; // v1 здесь статическая локальная?
 
    auto g = [&v1]() {return ++v1; }; // здесь постоянно привязяна по коду
 
    auto l = [v1]() {return v1 - 1; }; // а здесь просто константное локальное значение
    //---------------------------------------------
 
    int z = f(), ch = g() , c = l();
    v1 = 0;
    int y = f(), ss = g(), x = l();
    cout << "z = " << z << ", ch = " << ch << ", c = " << c << endl <<
        "y = " << y << ", ss = " << ss << ", x = " << x << endl;
    return 0;
}
И в целом лямбда, определив вызываемое выражение, пусть наше auto f = лямбда; Вызывая потом f(); ниже по коду мы подставляем выражение из определения?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.03.2016, 09:26
Ответы с готовыми решениями:

Лямбда-функция и mutable переменная
Добрый день! Есть такой код: void foo() { int id = 0; auto l = () mutable { std::cout &lt;&lt; id &lt;&lt; std::endl; ++id;...

Лямбда-выражения. Как описать лямбда-процедуру и передать в нее файловую переменную?
Погуглив не смогла найти ответов на свои вопросы. Есть следующая процедура, которая находит положительные числа в одном файле и...

Лямбда функции
Всем добрый вечер! Пытаюсь ознакомиться поближе с лямбда функциями и уже возникли трудности... Просмотрела пару публикаций на эту тему и...

6
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
13.03.2016, 10:27
Цитата Сообщение от yrceus Посмотреть сообщение
Спецификатор mutable определяет по списку захвата локальные статические переменные?
mutable, насколько мне известно, позволяет изменять переданные не ссылочные переменные, пример:
C++
1
2
3
4
5
int a = 1;
int b = 1;
int c = 1;
auto l1 = [a,&b,c] () { a = 10; b = 10; c = 10; } // ошибка для a и c, они read-only
auto l2 = [a,&b,c] () mutable { a = 10; b = 10; c = 10; } // ok
Цитата Сообщение от yrceus Посмотреть сообщение
иже по коду мы подставляем выражение из определения?
Скорее вызываем как функцию, ведь по сути f(); - это operator(); у лямбда-выражения.

Не по теме:

Экспертам, если что-то не так сказал, поправьте. :)



Добавлено через 1 минуту
А вообще вот тут про лямбды подробно написано, но только если английский знаете.

Добавлено через 2 минуты
Цитата Сообщение от yrceus Посмотреть сообщение
// v1 здесь статическая локальная?
С чего бы? Скорее локальная в лямбда-выражении или просто связана ссылкой с v1.
1
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337
13.03.2016, 11:11  [ТС]
GbaLog-, а вот так? Значение v1, как я понял, копируется в f(); и хранится там, допуская изменения.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    int v1 = 32;
 
    auto f = [v1]()mutable { return ++v1; }; // разве v1 не статическая?  
 
    int z = f();    // к 32 добавляем, z равно 33
    v1 = 0;         // v1 сама по себе, равна нулю теперь
    int y = f();    // добавляем к 33, y равно 34
 
    cout << "z = " << z << endl << "y = " << y << endl;
    return 0;
}
А вот по вашей ссылке на статью еще хитрее
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    int a = 1, b = 1, c = 1;
 
    auto m1 = [a, &b, &c]() mutable {
        auto m2 = [a, b, &c]() mutable {  
            std::cout << a << b << c << '\n';
            a = 4; b = 4; c = 4;
        };
        a = 3; b = 3; c = 3;
        m2();
    };
 
    a = 2; b = 2; c = 2;
 
    m1();                             // calls m2() and prints 123
    std::cout << a << b << c << '\n'; // prints 234
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,226
13.03.2016, 11:40
Лучший ответ Сообщение было отмечено yrceus как решение

Решение

Цитата Сообщение от yrceus Посмотреть сообщение
локальные статические переменные?
Я не понял: о каких локальных статических переменных идет речь? Ничего статического в коде я не вижу.

1. Код

C++
1
auto f = [v1]()mutable { return ++v1; };
эквивалентен коду

C++
1
2
3
4
5
6
7
8
class lambda1 
{
public:
  lambda1(int v1) : v1(v1) {}
  int operator ()() { return ++v1; }
private:
  int v1;
} f(v1);
Ключевое слово mutable в этом контексте привело к тому, что lambda1::operator () не является const и поэтому может изменять внутренние переменные класса. На переменную v1 в функции эти изменения никак не влияют.

2. Код

C++
1
auto g = [&v1]() {return ++v1; };
эквивалентен коду

C++
1
2
3
4
5
6
7
8
class lambda2
{
public:
  lambda2(int &v1) : v1(v1) {}
  int operator ()() const { return ++v1; }
private:
  int &v1;
} g(v1);
В этом случае оператор является const, но это нам не мешает внутри lambda2::operator () менять данные через ссылку v1, т.е. фактически переменную v1 из функции.

3. Код

C++
1
auto l = [v1]() {return v1 - 1; };
эквивалентен коду

C++
1
2
3
4
5
6
7
8
class lambda3
{
public:
  lambda3(int v1) : v1(v1) {}
  int operator ()() const { return v1 - 1; }
private:
  int v1;
} l(v1);
Без модификатора mutable в определении лямбды lambda3::operator () является const и поэтому не сможет менять содержимое класса.
4
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
13.03.2016, 14:59
Лучший ответ Сообщение было отмечено yrceus как решение

Решение

Цитата Сообщение от yrceus Посмотреть сообщение
Спецификатор mutable определяет по списку захвата локальные статические переменные?
по дефолту лямбда не изменяет собственного состояния во времени.
она не обладает собственным логическим состоянием.

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

C++
1
2
3
4
5
6
7
8
9
int main()
{
    int v=10;
 
    //  error: assignment of read-only variable ‘p’    
    auto lambda = [v]() {  v = 10;     };
    
    lambda();
}
что бы иметь возможность модифицировать захваченный контекст,
нужно указать ключевое слово mutable

это означает "мутабельная лямбда",
или "лямбда, у которой может быть своё собственное логическое состояние",
"лямбда, которая может модифицировать захваченный контекст"

C++
1
2
3
4
5
6
7
int main()
{
    int v=10;
    // теперь можно изменять члены-данные лямбды
    auto lambda = [v]() mutable {  v = 10;     };
    lambda();
}
2
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337
13.03.2016, 15:05  [ТС]
Ага, понял. Думалось, что лямбда это на подобии функции (поэтому про статику подумал), а это объект безымянного класса с одним константным методом. Теперь разъяснили) Огромное!
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
13.03.2016, 15:35
Лучший ответ Сообщение было отмечено yrceus как решение

Решение

Цитата Сообщение от yrceus Посмотреть сообщение
это объект безымянного класса с одним константным методом.
не совсем.

это верно, если лямбда не мутабельная:

http://rextester.com/OYJKV34796

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int main()
{
    std::cout << "Hello, world!\n";
    
    int v=10;
    auto lambda = [v]() {};
   
    std::cout <<"функция член operator() имеет вид:\n"
        << typeid( &decltype(lambda)::operator() ).name()
    <<'\n';
}
output:
Hello, world!
функция член operator() имеет вид:
void (__thiscall <lambda_6c9cf6dbefbd7dc5f3a6425b7d621963 >::*)(void)const
но если мутабельная, значит может менять своё состояние,
поэтому, компилятор сгенерирует не константную-функцию член:

http://rextester.com/BQOBC79413

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main()
{
    std::cout << "Hello, world!\n";
    
    int v=10;
    auto lambda = [v]() mutable { v = 10; };
    
    std::cout <<"функция член operator() имеет вид:\n"
        << typeid( &decltype(lambda)::operator() ).name()<<'\n';
}
output:
Hello, world!
функция член operator() имеет вид:
void (__thiscall <lambda_c296ced7b5c1fa5e2d8a0a7b0b19a039 >::*)(void)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.03.2016, 15:35
Помогаю со студенческими работами здесь

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

Лямбда функции
Помогите пожалуйста. Написать программу демонстрирующую лямбда функцию на с++. желательно с комментариями, а то я в этом совсем ничего не...

Функции и лямбда
Хотела оптимизировать функцию двух переменных по одному аргументу def error50(x): return error(50, x) res =...

Лямбда функции и QMenu
Можно ли засунуть лямбду в QMenu? Типо такого QMenuBar m; QMenu *mnu=new QMenu(&quot;&amp;Menu&quot;); QString s; ...

Передача лямбда в функции
В чем смысл передачи лямбда выражения функции?auto square = (int x) { return x * x; }; std::cout &lt;&lt; square(16) &lt;&lt;...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru