Лямбда-вирази у С++: відмінності між версіями

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