10

P2266's interaction with `decltype(auto)` – Arthur O'Dwyer – Stuff mostly about...

 3 years ago
source link: https://quuxplusone.github.io/blog/2021/05/04/p2266-decltype-auto/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

P2266’s interaction with decltype(auto)

C++Now 2021 is happening this week. Normally it’s in Aspen, Colorado, but this year it’s completely online. I presented two talks:

In my return x talk, slide 77 showed a table illustrating how P2266’s value-category changes affected five subtly different functions. One of the entries was incorrect; and, as I fixed it, I realized that for completeness the table should have included eight subtly different functions!

Here is a revised and I hope fully correct version of that table. This revised version appears in the slide deck I submitted after the talk.

C++14/17/20 P2266 (C++23?) auto a(T x) -> decltype(x) { return x; } T 1 T 1 auto b(T x) -> decltype((x)) { return (x); } T& T& auto c(T x) -> decltype(auto) { return x; } T 1 T 1 auto d(T x) -> decltype(auto) { return (x); } T& T&& auto e(T&& x) -> decltype(x) { return x; } ill-formed 2 T&& auto f(T&& x) -> decltype((x)) { return (x); } T& ill-formed 3 auto g(T&& x) -> decltype(auto) { return x; } ill-formed 2 T&& auto h(T&& x) -> decltype(auto) { return (x); } T& T&& 4

1) Implicit move: the returned T object is move-constructed from x.

2) The return type is deduced as T&&, but lvalue x cannot be returned as T&& without a cast. (C++20’s change to permit implicit-moving from rvalue reference variables is irrelevant. Implicit move is not considered, because this is not a copy-initialization context.)

3) The return type is T&; but xvalue x cannot be returned as T& without a cast.

4) In C++20, the return type is deduced as T& because the returned expression (x) is an lvalue. After P2266, the return type is deduced as T&& because the returned expression (x) is an xvalue.

Observe that in C++20, functions f and h both do “rvalue laundering,” accepting an rvalue reference and returning an lvalue reference, with no visible cast. After P2266, neither of them works anymore to launder rvalues: f becomes ill-formed, and h becomes the identity function.

And just for total completeness:

C++14/17/20 P2266 (C++23?) auto t(T& x) -> decltype(x) { return x; } T& T& auto u(T& x) -> decltype((x)) { return (x); } T& T& auto v(T& x) -> decltype(auto) { return x; } T& T& auto w(T& x) -> decltype(auto) { return (x); } T& T&


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK