Sì. Credo che il primo esempio sia sicuro, indipendentemente dal tempo di vita di tutti i temporari creati durante la valutazione dell'espressione completa che coinvolge l'espressione lambda senza cattura.
Per la bozza di lavoro (n3485) 5.1.2 [expr.prim.lambda] p6
Il tipo di chiusura per una lambda espressione senza lambda-acquisizione ha un non pubblico non virtuale funzione di conversione const esplicita al puntatore per funzionare con gli stessi parametri e tipi di ritorno della chiusura operatore di chiamata di funzione del tipo . Il valore restituito da questa funzione di conversione deve essere l'indirizzo di una funzione che, una volta invocato, ha lo lo stesso effetto del richiamo dell'operatore di chiamata di funzione del tipo di chiusura.
Il paragrafo precedente non dice nulla sulla validità del pointer-to-function che scade dopo la valutazione dell'espressione lambda.
Ad es., Mi aspetterei quanto segue per lavorare:
auto L = []() {
return [](int x, int y) { return x + y; };
};
int foo(int (*sum)(int, int)) { return sum(3, 4); }
int main() {
foo(L());
}
Mentre i dettagli di implementazione di clang non sono certo l'ultima parola su C++ (lo standard è), se ti fa sentire meglio, il modo in cui questo viene implementato in clang è che quando l'espressione lambda viene analizzata e analizzata semanticamente viene inventato un tipo di chiusura per l'espressione lambda e una funzione statica viene aggiunta alla classe con semantica simile all'operatore di chiamata di funzione del lambda. Quindi, anche se il tempo di vita dell'oggetto lambda restituito da 'L()' è finito nel corpo di 'foo', la conversione in pointer-to-function restituisce l'indirizzo di una funzione statica che è ancora valida.
Si consideri il caso in qualche modo analogo:
struct B {
static int f(int, int) { return 0; }
typedef int (*fp_t)(int, int);
operator fp_t() const { return &f; }
};
int main() {
int (*fp)(int, int) = B{};
fp(3, 4); // You would expect this to be ok.
}
io non sono certamente un esperto di core-C++, ma FWIW, questa è la mia interpretazione della lettera della norma, e sento che è difendibile.
Spero che questo aiuti.
"* Sì, lo è, come anche il secondo esempio. *" Pedanticamente parlando, il secondo esempio è illegale poiché prende l'indirizzo di un temporaneo, quindi non è né sicuro né pericoloso. ; -] – ildjarn
@ildjarn Hah, non se ne rendeva nemmeno conto, io idiota. Quindi cosa fare ora, tecnicamente l'intera risposta potrebbe essere spazzatura, poiché l'esempio lambda prende anche l'indirizzo di un temporaneo. Ma poi di nuovo è un lambda e la funzione stessa dovrebbe praticamente * "essere lì" * tutto il tempo. Forse è il momento di cogliere lo standard per quella che sembra essere una domanda piuttosto facile. –
L'esempio lambda non prende l'indirizzo di un temporaneo, converte semplicemente un oggetto lambda in un puntatore di funzione. Ad ogni modo, IMHO il tuo sarcasmo è fuori luogo. – enobayram