I'm interested to understand what exactly the trailing auto&& return type means, specifically as distinguished from decltype(auto), which doesn't work here, and an unspecified return type, which also doesn't work.
In the code below, fn returns the x_ field of the argument. When the argument is an lvalue, x_ comes back as an lvalue, etc.
In the examples of fn_bad[123], it seems to return int, even when an lvalue argument is provided. I can see why -> auto would cause this, but I expected -> decltype(auto) to return int&. Why does only -> auto&& work?
#include <utility>
struct Foo { int x_; };
int main() {
auto fn_bad1 = [](auto&& foo) -> decltype(auto) { return std::forward<decltype(foo)>(foo).x_; };
auto fn_bad2 = [](auto&& foo) -> auto { return std::forward<decltype(foo)>(foo).x_; };
auto fn_bad3 = [](auto&& foo) { return std::forward<decltype(foo)>(foo).x_; };
auto fn = [](auto&& foo) -> auto&& { return std::forward<decltype(foo)>(foo).x_; };
Foo a{};
fn(a) = fn(Foo{100}); // doesn't compile with bad1, bad2, bad3
}