Topic: Idea: Extension of structured bindings to definition
Author: Eyal Rozenberg <eyalroz@technion.ac.il>
Date: Sat, 26 Aug 2017 22:17:06 +0200
Raw View
(This was mis-posted earlier to std-discussion, sorry.)
----
Today ( = C++17 standard draft, with section [dcl.struct.bind] in
particular), we can define multiple variables using, say:
auto [ x, y ] = f();
where f() returns an array, or a tuple, or a struct with two members.
That's very nice and good.
Now, what if I wanted my new variables x and y to be members of a
struct? At the moment, I can only define a struct using types I can
specify in advance, e.g.
struct { int x; double y; } s;
and together with initialization, this becomes:
struct { int x; double y; } s = std::make_tuple(1, 2.3);
what I am imagining, or suggesting, is being able to write:
struct { auto x; auto y; } s = std::make_tuple(1, 2.3);
which is interpreted as though we've written
struct {
decltype(1) x;
decltype(2.3) y;
} s = std::make_tuple(1, 2.3);
with the possible initializers being anything that can be used as the
initializer for structured binding of x and y together as stand-alone
variables.
Motivation
-----------
Well, first there's the obvious Don't Repeat Yourself even in my simple
example.
Additional motivation is to be found if we consider why we have auto
variables in the first place, since C++11. It's good to be able to say
auto x { long_expression_with_difficult_type_to_figure_out };
rather than having to determine the type, or repeating yourself twice with
decltype(expression_with_difficult_type_to_figure_out) x {
expression_with_difficult_type_to_figure_out
};
Unfortunately, at the moment we lose this feature if x needs to be a
member of a struct - even if we know the type of the other members. I
can't say
struct {
decltype(a_2_tuple_with_difficult_first_type_and_double) x;
double y;
} s { a_2_tuple_with_difficult_first_type_and_double };
and my idea, or proposition, would make this possible.
This is also "better" than structured bindings in the sense that it lets
you convert a product type with unidentified components to one whose
components are identified, e.g.:
template<size_t N> std::array<widget_t, N> generate_widgets();
// ...
struct special_widgets {
auto foo; auto bar; auto baz;
} s = generate_widgets<3>();
Estimated Impact
----------------
I'm not a C++ language lawyer, but I think that this kind of syntax
should not clash with anything already existing in the language.
This is syntactic sugar, it seems, so it should not affect the
expressibility of C++.
This feature is close enough to what structured binding does already, so
that the burden on compiler authors to implement this would be very
limited (in my uninformed opinion).
Additional ideas if you want to get super wild
-----------------------------------------------
1. Allow multiple members of the same type like in usual struct
declarations, i.e.
struct { auto x, y; auto z; } s = std::make_tuple(1, 2, 3.4);
2. Allow only having some members be auto, i.e.
struct { auto x; double y; } s = std::make_tuple(1, 2.3);
3. Allow all-auto structs
auto struct { x, y } s = std::make_tuple(1, 2.3);
or perhaps
auto struct [ x, y ] s = std::make_tuple(1, 2.3);
if you like square brackets better.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/59dcbbbc-c536-4b7b-9c88-0638fb0cd58a%40technion.ac.il.
.