Ici il y a ce qu'il faut faire : https://stackoverflow.com/questions/29859796/c-auto-vs-auto (auto&&)
Maintenant la question c'est pourquoi il faut faire ça...
D'après ce que j'ai compris, ça reprend la règle des templates, donc si en template tu écris
template<class U> void f(const U& u)
avec U la classe inconnue, alors ça revient à écrire
const auto& u = expr;
avec auto la classe inconnue
https://stackoverflow.com/questions/7576953/c-auto-keyword-why-is-it-magic
A mon avis l'idée de la comparaison avec les templates (vu que l'algo de détermination de type est le même) est de dire que auto ne sélectionnera que le nom de la classe et pas les modificateurs d'utilisation de la classe (référence etc..). Donc si fnct() renvoit Foo&, alors l'algorithme qui détermine auto va lire seulement "Foo". M'enfin ça parait pas complet comme explication vu que les pointeurs sont pris en compte correctement.
J'ai l'impression que lui utilise l'argument de dire que t'as jamais une référence à droite de l'opérateur =: https://stackoverflow.com/a/20435077 . C'est pas impossible qu'il fasse référence aux rvalue/lvalue (ça fait longtemps que j'ai pas fais de C++ donc j'ai du mal à faire le lien de causalité entre ce qu'il dit et l'implémentation du cpp). C'est possible que même si la valeur de retour en elle même est une référence, le fait qu'elle soit utilisée comme une expression la transforme en rvalue puisque les références sont utilisées comme des objets. En gros il se dit: "c'est une référence utilisée en expression donc c'est l'objet que j'utilise". Et si t'utilises un pointeur, par contre le auto aura bien un pointeur puisque les pointeurs restent des pointeurs en expression (c'est *ptr qui désigne l'objet).
Je pense que les deux arguments se rejoignent, auto prend la classe de l'objet de droite. Ici l'objet de droite est une référence en rvalue donc l'objet en lui même, donc de type Foo.
Ici ils parlent de dangling reference : https://en.cppreference.ce.com/w/cpp/language/reference pour ce cas particulier. En gros l'objet retourné est une référence, mais l'objet meurt en dehors de l'expression.
Une fois tout ceci dit, je pense que ce que tu veux faire c'est:
Foo fnct() { ... return foo; }
auto&& f = fnct()
Je pense que l'opérateur de copie est pas appelé comme ça (copy elision https://en.cppreference.com/w/cpp/language/copy_elision ), et le retour d'une référence en fonction a pas d'utilité pour ce que je comprends
J'ai mis les références parce que ce que je dis se base surtout sur mon interprétation, chacun peut lire et mieux comprendre que moi la situation