Лямбда-вирази у С++: відмінності між версіями
[перевірена версія] | [перевірена версія] |
Вилучено вміст Додано вміст
м Категоризація за вмістом |
м заміна застарілого тегу source |
||
Рядок 5:
== Про лямбда-вирази ==
Багато мов програмування підтримують концепцію ''анонімних функцій'', які мають тіло, але не мають ім'я. Лямбда-вирази — це техніка програмування, пов'язана з анонімними функціями. Лямбда-вираз неявно задає клас об'єкта функції і створює функцію об'єкт цього класу. Приклад лямбда-виразу можна розглянути як параметр, що передається функції '''std::sort()'''
<
#include <algorithm>
#include <cmath>
Рядок 16:
}
</syntaxhighlight>
== Об'єкти функцій і лямбда-виразів ==
Рядок 26:
=== Граматика лямбда-виразів ===
Наступне формальне визначення виражає граматику зі стандарту [[ISO]] [[C++11]] (елементи з opt у дужках є необов'язковими)
<
lambda-introducer lambda-declarator(opt) compound-statement
</syntaxhighlight>
Відповідні компоненти синаксису виражаються так:
Рядок 59:
Наприклад, якщо тіло лямбда-виразу має доступ до змінної total по посиланню, а до змінної factor по значенню, наступні вирази еквівалентні:
<
[&total, factor]
[factor, &total]
Рядок 66:
[=, &total]
[&total, =]
</syntaxhighlight>
Часто люди припускаються таких помилок, зв'язаних з виразом фіксації:
<
struct S { void f(int i); };
Рядок 78:
[i, i]{}; // ERROR: i repeated
}
</syntaxhighlight>
==== Список параметрів ====
Рядок 88:
Можна використовувати специфікацію виключень '''throw()''', щоб вказати, що лямбда-вираз не створює виключних ситуацій. Як і в випадку зі звичайними функціями, [[компілятор]] С++ створює попередження, якщо лямбда-вираз оголошує специфікацію виключень '''throw()''' і тіло лямбда-функції викликає виключну ситуацію, як показано в наступному прикладі:
<
// throw_lambda_expression.cpp
// compile with: /W4 /EHsc
Рядок 95:
[]() throw() { throw 5; }();
}
</syntaxhighlight>
==== Значення, що повертається ====
Рядок 101:
Можна опустити вираз, що повертає значення у лямбда-виразі, якщо тіло лямбда-функції складається з одного [[return]], або нічого не повертає. Якщо лямбда-вираз складається з одного оператора '''return''', компілятор знаходить тип значення, що повертається з return-виразу, в противному випадку повертає значення [[void]].
<
auto x1 = [](int i){ return i; }; // OK: return type is int
auto x2 = []{ return{ 1, 2 }; }; // ERROR: return type is void, deducing
// return type from braced-init-list not valid
</syntaxhighlight>
==== Тіло лямбда-виразу ====
Рядок 121:
Крім того лямбда-вираз може мати доступ до змінних, які воно фіксує ([]) з зовнішньої області видимості. Явно за допомогою [expr], або неявно. Тіло лямбда-виразу використовує значення за замовчуванням для доступу до неявно зафіксованих змінних.
Наступний приклад демонструє фіксацію n явно по значенню, а m — неявно по посиланню.
<
#include <iostream>
Рядок 133:
cout << m << endl << n << endl;
}
</syntaxhighlight>
цей приклад виводить на консоль такий результат:
|