C++ Logo


Advanced search

Re: Public member lambdas ( auto-type and designated arguments )

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sun, 28 Nov 2021 19:13:11 -0500
On Sun, Nov 28, 2021 at 6:52 PM Cleiton Santoia via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> Em sex., 26 de nov. de 2021 às 21:51, Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> escreveu:
>> If you're going to propose something, there should probably be a
>> reason for it. You haven't explained what problems you're trying to
>> solve here.
> Sorry, the motivation is the same as any "named tuples" proposal discussion or this discussion and some of "named arguments" or "designated arguments", like the last example from named-parameters-in-c20, or 1:04s in D2288.
> Mostly it is about "more clear" function calls, and a handy shortcut for aggregate local classes.
> set_color( [red=200, green=10, blue=100] );
> vector<int> x ( [capacity=20, fill=15] );
> socket.open ( [port=2000, ip="localhost", timeout=1000] );// <- much better than open( 2000, "localhost", 1000 )
> auto calculate(const vector<float>& v ) {
> ...
> return [count, sum, mean=sum/count];
> }
> auto x = calculate(data);
> cout << x.sum; // x has count, sum and mean members without the need to define the class.
>> It uses square brackets, but the main C++ syntax that represents a sequence of
>> values is curly braces. Indeed, when it comes to multiple values,
>> square brackets are used to decompose sequences of values, not to
>> create them.
> Well, [] are used for other things, like indexing and attributes besides binding. I don´t think there is such "concept" of decompose with [] and compose with {}

And yet:

auto [val1, val2, val3] = std::tuple{expr1, expr2, expr3};

On the left is decomposition. On the right is initialization of an
object by a sequence of expressions.

So yes, C++ does have such a "concept". `{}`, braced-init-lists, are
standard syntax for initializing an object from a sequence of
expressions. C++20 even allows these expressions to be routed to
specific members of the object to be initialized if you're
initializing a class aggregate.

In a perfect world, any kind of language tuple proposal would use `{}`
syntax for the creation of a tuple. That is simply what would be
expected, since you are initializing an object from a sequence of

>> Using a lambda makes absolutely no sense here. Lambdas are callable
>> function objects; capturing values is simply a means to the end of
>> making that function useful.
> Kinda does, because this is the way c++ expands a lambda into a local class today, however the members are private, ( I don't think that is even mandated by the standard to be like that ) and making them public will probably be easy...

That's merely piggybacking on an implementation detail. It makes sense
only from the perspective of whatever already exists that looks
vaguely like the thing you're trying to make work.

> The biggest difference between this and designated initializers in function calls, is that you don't need to pre-define the class that you will use as a parameter.

Except you do, because nothing in your proposal suggests changing how
those work. Your proposal, as expressed in your initial e-mail, is to
allow a version of lambda syntax to create unnamed types with named
members. Nothing in that proposal changes how function *parameters*
work. You said nothing about a syntax to declare a function that takes
named parameters.

So the only way to pass this unnamed type to some other function is if
that is passed as a template function through template argument
deduction. So the only way to use this as a way to have named
parameters is to write all your functions as:

template<typename Params>
auto func(Params params)
  return params.param1 + params.param2;

That's not feasible. Nor does it solve the forwarding problem with
regard to named, variadic parameters.

Received on 2021-11-28 18:13:23