Я поиграл с некоторыми новыми функциями в C ++ 11 и попытался написать следующую программу, ожидая, что она не будет работать.К моему большому удивлению, это происходит (в GCC 4.6.1 в Linux x86 с флагом 'std = c ++ 0x'):
#include <functional>
#include <iostream>
#include <memory>
std::function<int()> count_up_in_2s(const int from) {
std::shared_ptr<int> from_ref(new int(from));
return [from_ref]() { return *from_ref += 2; };
}
int main() {
auto iter_1 = count_up_in_2s(5);
auto iter_2 = count_up_in_2s(10);
for (size_t i = 1; i <= 10; i++)
std::cout << iter_1() << '\t' << iter_2() << '\n'
;
}
Я ожидал, что «from_ref» будет удален при каждом выполнениииз возвращенных лямбда-трасс.Вот мое рассуждение: после запуска count_up_in_2s, from_ref выталкивается из стека, но поскольку возвращаемая лямбда не обязательно запускается сразу, так как она возвращается, в течение короткого периода не существует другой ссылки, пока эта же ссылка не будетотодвинулся, когда лямбда фактически запускается, поэтому не должен ли счетчик ссылок shared_ptr достигать нуля, а затем удалять данные?
Если захват лямбда-кода в C ++ 11 не намного умнее, чем я его даюкредит на который, если это так, я буду рад.Если это так, могу ли я предположить, что захват переменных в C ++ 11 разрешит все лексические хитрости определения / закрытия а-ля Лисп, пока / что-то / заботится о динамически распределенной памяти?Могу ли я предположить, что все захваченные ссылки будут оставаться в живых до тех пор, пока сама лямбда не будет удалена, что позволит мне использовать smart_ptrs вышеуказанным способом?
Если это так, как я думаю, это не означает, что C ++11 позволяет выразительное программирование высшего порядка?Если так, то я думаю, что комитет C ++ 11 проделал отличную работу =)