C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Make closure type structural

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Sun, 19 Nov 2023 12:24:46 +0100
niedz., 19 lis 2023 o 10:25 Chromo Runge <rungecc_at_[hidden]> napisał(a):
>
> > Do you mean that this code should be correct too
>
> No, it's my mistake. It shall be `constexpr auto plus ...`. Template parameter should be constexpr usable.
>

Ok, then it makes more sense.

> Marcin Jaczewski <marcinjaczewski86_at_[hidden]> 于 2023年11月19日周日 16:27写道:
>>
>> niedz., 19 lis 2023 o 07:18 Chromo Runge via Std-Proposals
>> <std-proposals_at_[hidden]> napisał(a):
>> >
>> > Currently, after CWG2452(https://cplusplus.github.io/CWG/issues/2542.html) was solved by simply making all closure types non-structural, the below example (from cppref) becomes ill-formed:
>> >
>> > ```c++
>> >
>> > auto plus = [](int a, int b) { return a + b; };
>> > auto forty_plus_cpp26 = std::bind_front<plus>(40);
>> >
>> > ```
>> >
>> > The workaround is changing the template parameter `plus` to `+plus`, which implicitly converts the closure type to a function pointer. But this only works with capture-less non-generic lambda.
>> >
>> > This is pretty astonishing since a lambda with no capture has already met the original requirements for a structural class type: [temp.parm]/7:
>> >
>>
>> Do you mean that this code should be correct too:
>> ```
>> auto i = 10;
>> auto foo = bar<i>();
>> ```
>> ?
>>
>> My answer is no. to be template parameter value need be constexpr, and
>> its same for lambda.
>> `+plus` probably works only because the return value is `constexpr`.
>>
>> > > a literal class type with the following properties:
>> > > - all base classes and non-static data members are public and non-mutable and
>> > > - the types of all bases classes and non-static data members are structural types or (possibly multidimensional) array thereof.
>> >
>> > Since closure type with no capture has no non-static data member (and no base class, obviously), then the non-static members of it surely are all public, non-mutable and structural by vacouse truth principle.
>> >
>> > So the first thing I would propose here is to make a closure type with no capture structural. This would make the above example valid (as before the solution to CWG2452 was adopted). There's no difficulty in the implementation, today, msvc, gcc and clang all accept this (https://godbolt.org/z/K6TvYfhYr).
>> >
>> > The second proposal is more subtle, we want to make the captured closure type also (possibly, if the captures are all structural) structural. It is actually possible, since though we alter the definition of the structural class type in the future to allow class like `string_view` to be structural (one possible way is allowing user defining a `structural equal to operator` which converts a non-structural type into a structural type), those changes shall not bother the structurality of closure type itself, since user could not provide any member functions (other than `operator()`), friend functions for a closure type. Thus, we could actually treat all captured members public and non mutable (the mutable specifier in the lambda declaration belongs to lambda's operator()). (Currently, only gcc allows this: https://godbolt.org/z/KT3aerWjd)
>> >
>> > It would be nice to just accept Proposal 1, since in most cases a constexpr-usable capture need not to be captured.
>> > --
>> > Std-Proposals mailing list
>> > Std-Proposals_at_[hidden]
>> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-11-19 11:24:59