Следуя этому ответу Теперь мне интересно, что такое правила для жизни lambdas и как связаны с временем жизни указателей функций, которые создаются путем автоматического преобразования, Существует несколько вопросов о времени жизни лямбда (например, здесь и здесь), и в этом случае ответы "они ведут себя точно так же, как вы сами написали весь объект-функтор", однако ни одно из них не обращается к указателю на функцию, что вполне разумно может быть частным случаем.
Я собрал этот небольшой рабочий пример, который иллюстрирует мою озабоченность:
#include <iostream>
typedef int (*func_t)(int);
// first case
func_t retFun1() {
static auto lambda = [](int) { return 1; };
// automatically converted to func_t
return lambda;
}
// second case
func_t retFun2() {
// no static
auto lambda = [](int) { return 2; };
// automatically converted to func_t and
// the local variable lambda reaches the end of its life
return lambda;
}
int main() {
const int a = retFun1()(0);
const int b = retFun2()(0);
std::cout << a << "," << b << std::endl;
return 0;
}
Хорошо ли это определено для обоих случаев? Или только для retFun1()
? Возникает вопрос: "является ли функция, указатель которой указывает на функцию, чтобы вызвать объект-функтор или переопределить тело в отдельной функции?" Любой из них имел бы смысл, но тот факт, что преобразование в указатель на функцию специально требует захвата без лямбды, предполагает, что он может быть последним.
Поставьте другой путь - я вижу, по крайней мере, два разумных способа, которые компилятор может захотеть реализовать такими лямбдами. Одна возможная юридическая реализация может заключаться в том, что компилятор должен синтезировать код, например:
func_t retFun3() {
struct __voodoo_magic_lambda_implementation {
int operator()(int) const {
return 3;
}
static int plainfunction(int) {
return 3;
}
operator func_t() const {
return plainfunction;
}
} lambda;
return lambda;
}
и в этом случае варианты static
и non static
retFun
будут в порядке. Если, однако, законным для компилятора является реализация лямбда:
static int __voodoo_impl_function(int x);
static struct __voodoo_maigc_impl2 {
int operator()(int) const {
return 4;
}
operator func_t() const {
return __voodoo_impl_function;
}
} *__magic_functor_ptr;
static int __voodoo_impl_function(int x) {
return (*__magic_functor_ptr)(x);
}
func_t retFun4() {
__voodoo_maigc_impl2 lambda;
// non-static, local lifetime
__magic_functor_ptr = λ //Or do the equivalent of this in the ctor
return lambda;
}
то retFun2()
- поведение undefined.