Date: Thu, 30 Jan 2020 14:13:10 +0200
Hello, after reading this blog post about the failed abbreviated lambda
attempt https://brevzin.github.io/c++/2020/01/15/abbrev-lambdas/
I wanted to share how I see some possible solutions.
The post cites 3 major issues
- Differing semantics with regular lambdas
- Arbitrary lookahead parsing
- Mismatch between the trailing-return-type and the body
*The first issue *(different return semantics reference vs value) can be
solved by reusing the decltype keyword to mark "return by ref cases"
auto f = [](int const* p) { return *p; } //< Both return by value
auto g = [](int const* p) => *p; //<
auto g = [](int const* p) => decltype *p; //< switch the return type to
const int& (as-if decltype(auto))
Note that in both abbreviated cases, the expression is SFINAE-friendly.
Having decltype is only about return type, not SFINAE tricks
*The second issue* (parsing overhead when types are removed from arguments)
can be solved for lambdas alone relatively easily.
We could introduce arguments *without* parenths.
[] => "Hello"; //< no argument
[] name => "Hello, " + name; //< one argument
[] a, b => a.id() < b.id(); //< two arguments
Should work with body block as well
[] name { auto h = "Hello, "; h += name; return h; };
It will *not* be allowed to have a type-only argument(s), but should be
allowed to have types optionally
[] String greet, name => greet + name; //< OK, type & name and name only
[] String, name => "Hello, " + name; //< FAILS, type only
*The last one*. This issue seems to be only solvable by not "just"
"expanding" the terse
[](auto&& a, auto&& b) => a.id() < b.id();
to a
[](auto&& a, auto&& b) -> decltype((a.id() < b.id())) noexcept(noexcept(a.id()
< b.id())) { return a.id() < b.id(); }
But instead adding explicit wording how the SFINAE would work in
terse-lambda expressions.
In particular, the fact that any identifiers that are not arguments should
be looked up as captures and not as arguments/variables from the enclosing
scope.
In a way this will make SFINAE semantically correct, testing the expression
as in-body, not as arbitrary an expression outside the function/lambda.
Thanks
attempt https://brevzin.github.io/c++/2020/01/15/abbrev-lambdas/
I wanted to share how I see some possible solutions.
The post cites 3 major issues
- Differing semantics with regular lambdas
- Arbitrary lookahead parsing
- Mismatch between the trailing-return-type and the body
*The first issue *(different return semantics reference vs value) can be
solved by reusing the decltype keyword to mark "return by ref cases"
auto f = [](int const* p) { return *p; } //< Both return by value
auto g = [](int const* p) => *p; //<
auto g = [](int const* p) => decltype *p; //< switch the return type to
const int& (as-if decltype(auto))
Note that in both abbreviated cases, the expression is SFINAE-friendly.
Having decltype is only about return type, not SFINAE tricks
*The second issue* (parsing overhead when types are removed from arguments)
can be solved for lambdas alone relatively easily.
We could introduce arguments *without* parenths.
[] => "Hello"; //< no argument
[] name => "Hello, " + name; //< one argument
[] a, b => a.id() < b.id(); //< two arguments
Should work with body block as well
[] name { auto h = "Hello, "; h += name; return h; };
It will *not* be allowed to have a type-only argument(s), but should be
allowed to have types optionally
[] String greet, name => greet + name; //< OK, type & name and name only
[] String, name => "Hello, " + name; //< FAILS, type only
*The last one*. This issue seems to be only solvable by not "just"
"expanding" the terse
[](auto&& a, auto&& b) => a.id() < b.id();
to a
[](auto&& a, auto&& b) -> decltype((a.id() < b.id())) noexcept(noexcept(a.id()
< b.id())) { return a.id() < b.id(); }
But instead adding explicit wording how the SFINAE would work in
terse-lambda expressions.
In particular, the fact that any identifiers that are not arguments should
be looked up as captures and not as arguments/variables from the enclosing
scope.
In a way this will make SFINAE semantically correct, testing the expression
as in-body, not as arbitrary an expression outside the function/lambda.
Thanks
Received on 2020-01-30 06:15:58