В Objective-C мы знаем, что блоки имеют 3 реализации во время выполнения.
NSGlobalBlock
— это синглтон во время выполнения, и он создается, если мы не используем значения переменных стека.NSStackBlock
— это не синглтон, он размещен в стеке (а не в куче), и он создается, когда мы используем некоторые переменные стека.NSMallocBlock
— это распределяется в куче, и это используется, когда мы хотим сохранить блоки как ivar или свойство некоторого класса, или где-нибудь в куче, т.е. @property (nonatomic, copy) MyBlockType myBlock;
или когда мы используем Block_copy()
функция. Это действительно важно, потому что NSMallocBlock сохраняет объекты из контекста, и этот факт может создать некоторые собственные циклы, если мы не используем правильные блоки.Итак, мой вопрос: «Где я могу найти полное объяснение времени выполнения лямбда-кода C ++ и как они обрабатываются компилятором? Или вы могли бы объяснить это? Существуют ли какие-либо конкретные проблемы с управлением памятью с помощью лямбда-выражения C ++? Где расположены лямбда-выражения? куча или в стеке?
Реализация Lambdas зависит от компилятора.
Стандарт не указывает, где он размещен в памяти, но как правило, они примерно эквивалентны функторы старой школы и они, и их захваченные значения копируются в стек, как и любой обычный объект.
Например.
std::vector<int> v{10,11,12,13};
std::for_each(v.begin(), v.end(), [](int& i) {i++;});
будет просто функция без гражданства.
Или же,
std::vector<int> v{10,11,12,13};
int C = 10;
int D = 20;
std::for_each(v.begin(), v.end(), [C,&D](int& i) {i += C + D;});
будет эквивалентно функтору, построенному в стеке с копией C
и ссылка на D
как его члены (но, вероятно, будут оптимизированы).
Единственный раз, когда вы действительно помещаете лямбда-объект в кучу, это когда он преобразуется в std::function
То, как это сделано, зависит от реализации компилятором std::function
,
void g(const std::function& f);
// ...
auto f = [=](int& i){i += C;}; // still on the stack (compiler-specific type)
g(f); // std::function constructed, possibly on the heap
Других решений пока нет …