Как стать автором
Обновить

Комментарии 19

НЛО прилетело и опубликовало эту надпись здесь
Собственно мне от замыканий нужно было только их определение по ходу кода. Возможно ли это как-то сделать «по старинке»?
НЛО прилетело и опубликовало эту надпись здесь
Красивый код, спасибо.

Правда, есть пару замечаний
1. То, что Вы называете замыканиями — это лямбда функции, а замыкание это нечто другое:

boost::function< int ( int ) > make_adding_func( int t )
{
	return [=]( int a ){ return a + t; };
}

...

auto f = make_adding_func( 5 );

assert( f( 10 ) == 15 );





Вот эта функция возвращает лямбда функцию, которая замыкается вокруг t.
Прошу прощения, отправилось рановато…

Красивый код, спасибо.

Правда, есть пару замечаний:

1. То, что Вы называете замыканиями — это лямбда функции, а замыкание это нечто другое:

boost::function< int ( int ) > make_adding_func( int t )
{
	return [=]( int a ){ return a + t; };
}

...

auto f = make_adding_func( 5 );

assert( f( 10 ) == 15 );

auto g = make_adding_func( 7 );

assert( g( 10 ) == 17 );

В этом коде f и g — это замыкания вокруг 5 и 7 соответственно.

2. Я копался во внутреннем устройстве лямбда функций, они не могут быть сконвертированы в указатель принципиально, т.к. на самом деле являются функторами (классами с оператором скобочки), у них есть конструктор, деструктор и т.п. (попробуйте сами поотлаживать с включенным ассемблерным листингом). [вышесказанное справедливо для MSVC2010]
Не вдаваясь в подробности, замыкания — это такие объекты, которые позволяют создавать функции прямо в теле других функций.

Не хочу показаться занудой, но то, что описали вы называется First-class function. Замыкания же — это подмножество first-class функций, которые используют переменные из окружающего контекста без передачи их в качестве параметров.
Я думаю, смысл понятен — замыкание — это лямбда ф-я, которая захватила что-то из контекста, если ничего не захвачено, то это просто лямбда ф-я, а не замыкание, я просто старался это показать как можно более наглядно :)

з.ы.

Замыкания же — это подмножество first-class функций, которые используют переменные из окружающего контекста без передачи их в качестве параметров.

полностью согласен :)
Кстати, название «лямбда-функция» неверное. Корректный термин — «лямбда-выражение».
А что мешает использовать boost::function? Или даже std::function раз уж говорим о новом стандарте.
Можете привести пример, как подобное реализуется с помощью boost::function и std::function?
Повторюсь — главным приоритетом для меня было удобное определение функций по ходу кода, а не в отдельных функциях, чтобы не скакать туда-сюда по исходнику.

На сколько я помню, я отказался от std::function, так как не смог его использовать с Intel Compiler.
void do_print(std::function<int (int)> func)
{
	for (int i = 0; i < 10; ++i)
	{
		cout << func(i) << " ";
	}
	cout << endl;
}

do_print( [](int x){ return x*x*x; } );


P.S. gcc 4.5
Такой способ не позволяет использовать std::function вместо указателей на йункцию, а именно это было нужно для моих задач
Это имеет смысл только в случае, если указатель на функцию используется в чужом (библиотечном) коде в качестве callback или чего-то вроде. Если do_print — своя функция, std/boost function лучше подходит.
В gcc скомпилировалось только в таком виде:
template int closureToFunction(int x){
CL cl;
return (*cl)(x);
}
#define CLOSURE_TO_FUNCTION(cl) closureToFunction <decltype(&cl)>
int main()
{
auto cube = [](int x){return x*x*x;};
printFunctionTable(CLOSURE_TO_FUNCTION(cube));
return 0;
}
При этом замыкания-то собственно не происходит:
int a = 5;
auto cube = [=](int x){return a*x*x*x;};
..\src\test2.cpp: In function 'int closureToFunction(int) [with CL = main()::<lambda(int)>*]':
..\src\test2.cpp:199:15: error: 'cl' is used uninitialized in this function
комент ниже
В коментах уже выяснили, что я немного напутал в терминологии, назвав лямбды замыканиями. Кстати в Intel Compiler код компилится, но выводит нули.
не туда написал — это к сообщению megalol'a
Да и хрен с ними. Из-за разных особенностей получается, что все зависит от внутреннего типа лямбды, который у каждого компилятора разный. Вот это плохо.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории