Le problème, c'est votre lambda. Il ne fait pas ce que vous pensez que cela fonctionne:
function<const A&(const A& r)> foo1 = [](const A& r) {
// ~~~~~~
return r;
};
Notez qu'il n'y a pas de fuite de type de retour. Cela signifie qu'il est automatiquement déduit. La déduction ne donne jamais de vous un type de référence, de sorte que cette lambda retourne un A
, pas un A const&
. Qui est revenu temporaire A
est lié au rendement A const&
de function
s' operator()
. Que temporaire n'est pas la durée de vie prolongée. Mais le temps de terminer l'appel foo1()
,, nous avons une balançant de référence pour que temporaire A
. C'est un comportement indéfini, qui, j'imagine, avec votre compilateur, vous a donné une utile d'erreur à l'exécution.
Pour résoudre ce problème, vous devez spécifier explicitement le type de retour:
function<const A&(const A& r)> foo1 = [](const A& r) -> A const& {
return r;
};
Mais même cela est dangereux, car vous pouvez toujours passer un temporaire A
dans cette fonction et d'obtenir un bancales référence. Pas de véritable moyen de contourner cela.
La facilité de tomber dans ce piège est également LWG Question 2813