C++ Logo

std-proposals

Advanced search

Public member lambdas ( auto-type and designated arguments )

From: Cleiton Santoia <cleitonsantoia_at_[hidden]>
Date: Fri, 26 Nov 2021 18:44:10 -0300
I have an idea for relaxing lambda syntax
Please, tell me if it´s a non-starter or if it may be something interesting.

1 - Permit lambdas defined only by the capture, making '{}' optional, so auto
x = [a=10, b=20] becomes a valid lambda, and when there is no {} and no
'()' ( parents are already optional ) the data members become public,
permitting access, and avoiding ABI problems with current lambdas.
2 - Also, all constant captures should be initialized thru initializers, in
the lambda_xx internal class, allowing default construction if all captures
are constants.

TLDR Sample:

    x = 10;
    auto a = [x,y=20];
    std::cout << '(' << a.x << ',' << a.y << ')';

Longer version :

1 "Sort of" named parameters:

Sample:
given:

    void rect(int x1, int y1, int x2, int y2) {...}

one can make a wrapper:
    void rect( auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }

and call like this :
    rect( [x2=30,y1=10,x1=10,y2=30] ); // unordered members passed as a
lambda

or even using concepts

    template <class T>
    concept rect_top_width = requires(T t) {
       { t.top } -> std::same_as<int>; { t.left } -> std::same_as<int>;
       { t.height } -> std::same_as<int>; { t.width } -> std::same_as<int>;
    };

    template <class T>
    concept rect_4ints = requires(T t) {
        { t.x1 } -> std::same_as<int>; { t.y1 } -> std::same_as<int>;
        { t.x2 } -> std::same_as<int>; { t.y2 } -> std::same_as<int>;
    };

    template <class T>
    concept rect_2points = requires(T t) {
        { t.a.x } -> std::same_as<int>; { t.a.y } -> std::same_as<int>;
        { t.b.x } -> std::same_as<int>; { t.b.y } -> std::same_as<int>;
    };

one can make different wrappers

    void rect( rect_top_width auto r ) { rect(r.left, r.top, r.left +
r.width, r.top + r.height); }
    void rect( rect_4ints auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }
    void rect( rect_2points auto r ) { rect(r.a.x, r.a.y, r.b.x, r.b.y); }

    rect( [height=220,top=30,left=10,width=304] ); // unordered members
    rect( [b=[y=10, x=10], a=[x=80,y=80]] ); // unordered members

    widget w; // assuming widget has top/left/width/height members
    rect( w ); // the function rect(rect_top_width) will be called

    struct point { int x, y; };
    point a{10, 20}, b{50, 60};
    rect( [a,b] ); // one can mimic a 'rectangle' structure without
defining it


2 "Sort of" less harmless ( i hope ) auto-types in structures.

    The possibility of a structure like X was proposed, in n3897
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3897.html>
    struct X {
      auto i = c; // probably not possible in auto-type
      auto s = "10"sv;
      auto f = 10.8;
      auto foo1 = [] (auto p) { return p * 2; };
    };

     Allowing public member lambdas, and member const initialization:

        const int c = 20;
        auto x = [i=c,
                 s="10"sv,
                 f=10.8,
                 foo1 = [](auto v) {
                     return v * 2;
                 }];
        using X = decltype(x); // X should be default constructible now

     I would like to use the syntax decltype( [lambda]... ) but due to
unevaluated context problems it's not possible.

Thanks
BR[]

Received on 2021-11-26 15:44:24