C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Idea of Lambda Classes
From: Magnus Fromreide (magfr_at_[hidden])
Date: 2021-01-12 01:45:25


I think the basic problem is that you can't write a constructor for an
anonymous class and that there are some limitations on where classes can
be declared. Once those problems are solved the rest follows naturally.

If we assume that one could spell the constructor of a class as class(arglist)
and that anonymous class instantiations are allowed as expressions then

TestInterface(
  struct : ISomeInterface {
    struct(std::string in1, std::string in2) : one(in1), two(in2) { }
    auto& self() { return *this; }
    void Function1() { std::cout << one << std::endl; }
    void Function2() { std::cout << two << std::endl; }
    std::string one, two;
}(a, b).self());

becomes quite natural.

On Tue, Jan 12, 2021 at 01:01:28AM -0500, Scott Michaud via Std-Proposals wrote:
> Yeah I wasn't saying that was an alternative. I was just looking into the
> problem and found something that's almost worthy of a "does this compile???"
> blog post.
>
> If I would do it in practice, then I would just manually bind the members
> like:
>
> https://godbolt.org/z/M9h56M (perhaps with raw pointers because lifecycle's
> known)
>
> Some sort of "lambda-like" syntax would be slightly cleaner than that, and
> allow things to be bound by reference.
>
> Not sure the ramifications of dedicating the syntax, though, or whether it
> would be heavily adopted, etc.
>
>
> On 1/12/2021 12:52 AM, Andrew Tomazos wrote:
> > Right, so the motivation of the proposal is to avoid the clutter of all
> > that extra boilerplate / plumbing. Same motivation as regular (function)
> > lambdas.
> >
> > On Tue, Jan 12, 2021 at 5:45 AM Scott Michaud <scott_at_[hidden]
> > <mailto:scott_at_[hidden]>> wrote:
> >
> > Oh I just came up with a smelly hack for this.
> >
> > Godbolt: https://godbolt.org/z/xe5oEz <https://godbolt.org/z/xe5oEz>
> >
> > On 1/12/2021 12:25 AM, Andrew Tomazos wrote:
> > > ie like below, see how argv is captured:
> > >
> > > class ISomeInterface
> > > {
> > > public:
> > >     virtual void Function1() {}
> > >     virtual void Function2() {}
> > > };
> > >
> > > void TestInterface(ISomeInterface& inObject)
> > > {
> > >     inObject.Function1();
> > >     inObject.Function2();
> > > }
> > >
> > > int main(int argc, char** argv)
> > > {
> > >     TestInterface([&]: ISomeInterface {
> > >         void Function1() override
> > >         {
> > >             std::cout << "One!" << *argv[0]* << std::endl;
> > >         }
> > >
> > >         virtual void Function2() override
> > >         {
> > >             std::cout << "Two!" << *argv[1]* << std::endl;
> > >         }
> > >
> > >     });
> > > }
> > >
> > > On Tue, Jan 12, 2021 at 5:20 AM Andrew Tomazos
> > > <andrewtomazos_at_[hidden] <mailto:andrewtomazos_at_[hidden]>> wrote:
> > >
> > > Right, but it doesn't have the lambda capture functionality.
> > >
> > >
> > > On Tue, Jan 12, 2021 at 5:18 AM Scott Michaud
> > > <scott_at_[hidden] <mailto:scott_at_[hidden]>> wrote:
> > >
> > > Andrew,
> > >
> > > Wouldn't this be equivalent to a local, unnamed class?
> > >
> > > Godbolt: https://godbolt.org/z/ezn8va
> > > <https://godbolt.org/z/ezn8va>
> > >
> > >
> > > On 1/11/2021 11:55 PM, Andrew Tomazos via Std-Proposals
> > > wrote:
> > > > I have an idea for a language feature we'll call Lambda
> > > > Classes.
> > > >
> > > > As placeholder syntax let's say like:
> > > >
> > > >     lambda-class:
> > > >         lambda-introducer : base-specifier-list_opt {
> > > > member-specification_opt }
> > > >
> > > > So for example:
> > > >
> > > >     auto my_lambda_class = [cap1,cap2]: {
> > > >         void f() { /*...*/; }
> > > >         void g() { /*...*/; }
> > > >     };
> > > >
> > > > A lambda class is to a normal class object as a lambda
> > > > function is to a normal function.
> > > >
> > > > A lambda class is an expression that is introduced with
> > > > the usual capture sequence, but is followed by a colon,
> > > > a (possibly empty) base class list, and then a class
> > > > definition body.
> > > >
> > > > It constructs a new anonymous class type in the same
> > > > fashion as a normal lambda, capturing any variables as
> > > > specified in the lambda-introducer, derives the new
> > > > class type from any bases in the base-specifier-list,
> > > > and adds any members given in the member-specification,
> > > > and the value of the expression is the (singular) object
> > > > of that new class type.
> > > >
> > > > The motivation is that there are many use cases where an
> > > > API asks for an object of a class type that implements
> > > > some interface - either implementing a (virtual)
> > > > polymorphic interface (run-time polymorphism) in
> > > > traditional OOP, or that models a certain concept
> > > > (compile-time polymorphism) in template meta-programming
> > > > - and in many of both of those use case families, the
> > > > response is to create a single-use class is created just
> > > > to adapt to that API.  Like lambda functions, lambda
> > > > classes help remove a lot of the boilerplate and
> > > > indirection in such use cases.
> > > >
> > > > Let me know if there is any enthusiasm for this and I'll
> > > > write up a proper draft.
> > > >
> > > >

> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups