Ответ 1
С++ 11: Нет. Каждое выражение лямбда имеет, я цитирую (§5.1.2/3):
[...] a уникальный, неназванный тип неединичного класса [...]
Это эффективно означает, что вы не можете знать тип лямбда, не зная сначала соответствующего выражения.
Теперь, если вы ничего не захватили, вы можете использовать преобразование в указатель функции и вернуть его (тип указателя функции), но это довольно ограничивает.
Как отметил @Luc в Lounge, если вы захотите заменить свой make_counter
(и если он не является шаблоном или не перегружен или что-то еще), будет работать следующее:
auto const make_counter = [](int i = 0) {
return [i]() mutable { return i++; };
};
С++ 1y: Да, через вывод возвращаемого типа для нормальных функций (N3582).