Вы никогда не можете знать тип лямбда-функции, потому что логически происходит то, что компилятор генерирует (локальный) класс с перегруженным оператором вызова функции, и лексическое замыкание представляется членами данных этого (локального) класса. Это то, что логически происходит с лямбда-функцией, такой как:
auto foo = [](int x, int y) { return x + y; };
Компилятор логически делает это:
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
Поскольку компилятор генерирует (локальный) класс, он генерирует имя, и, следовательно, вы никогда не можете явно написать тип, вы можете вывести тип только из выводов типа аргументов функции шаблона или с помощью auto / decltype.
Кроме того, замыкания C ++ 0x размещаются статически, поэтому вы все равно не можете безопасно вернуть необработанное замыкание C ++ 0x.
И все же есть несколько способов, которыми вы можете достичь этого, первый более гибкий и поддерживает лямбда-функции, которые захватывают лексические области. Используйте std :: function, если у вас есть лямбда-функция, которая ничего не захватывает из внешней области видимости, тогда вы можете использовать указатели на функции, но это преобразование больше для работы с унаследованным кодом, чем что-либо.
Итак, в основном вы хотите вот что:
std::function< int (int) > foo(int x)
{
return [x](int y)->int{return x * y;};
}
Причина, по которой я продолжал говорить логически, заключается в том, что именно так изначально работает boost :: lambda (даже несмотря на то, что C ++ 03 не позволяет использовать локальные классы в аргументах функции шаблона) и в чем идея добавления Лямбда-функции берут свое начало, но поскольку это языковая функция, теперь производители компиляторов могут реализовывать ее различными и более эффективными способами, например, при захвате всей среды по ссылке компилятор может просто передать указатель на стек вызовов вместо логического способа, в то же время поддержание логического представления.