Jonas Lund
2018-11-11 21:06:43 UTC
Rationale:
C++20 designated initialization for objects is a great quality of life
improvement but right now only goes half the way and with small changes
could promote constant usage and improve code quality.
In scenarios where an object copy is made but only a small part of the
members needs updating this could lead to far better code with relatively
small changes.
Example:
Given:
struct vec3 { float x,y,z; };
vec3 oldvec{1,2,3};
You can write (old):
vec3 newvec(oldvec);
newvec.y=20;
C++20 now lets you do:
vec3 newvec{ .x=oldvec.x , .y=20 , .z=oldvec.z };
This proposal would enable:
vec3 newvec{ ...oldvec , .y=20 };
Effort needed to implement:
Should be relatively low effort, no new keywords and C++20 already has
added designated initializers and this should be able to build on that.
Syntax rules:
Within an aggregate initialization while the rest operator (...) is
encountered at the beginning of a list (in the same place a designatede
initializer would be) the ... is expected to be followed by an value that
is the source value to pick members from, the compiler should allow for
multiple source values.
AFTER the last rest operator has been found there can only be additional
designated initializers.
(Putting spreads after designated initializers makes little sense if
following the semantics below)
IE:
T object * {* *.*designator *=* arg1 *,* *.*designator *{* arg2 *} *... *};*
would become
T object * {* ...sarg1, ...sarg2 , <SNIP> *.*designator *=* darg1 *,* *.*
designator *{* darg2 *} *<SNIP> *};*
(<SNIP> is used above since ... would be ambigious in this case)
sarg1, sarg2 are source objects whilst darg1 and darg2 are direct values.
Semantics:
The compiler should expand all members from each source arg(sarg) in
left-to-right order, the expanded members if overridden by other spreads or
explicitly given designated initializers should be ignored.
The spreading should occur on a visible OR public per-name basis, thus a
source-arg need not be of the same type as the object being initialized and
multiple objects of different types can be used to initialize one
destination object.
Spreading a member that does not exist in the destination must not be
allowed.
C++20 designated initialization for objects is a great quality of life
improvement but right now only goes half the way and with small changes
could promote constant usage and improve code quality.
In scenarios where an object copy is made but only a small part of the
members needs updating this could lead to far better code with relatively
small changes.
Example:
Given:
struct vec3 { float x,y,z; };
vec3 oldvec{1,2,3};
You can write (old):
vec3 newvec(oldvec);
newvec.y=20;
C++20 now lets you do:
vec3 newvec{ .x=oldvec.x , .y=20 , .z=oldvec.z };
This proposal would enable:
vec3 newvec{ ...oldvec , .y=20 };
Effort needed to implement:
Should be relatively low effort, no new keywords and C++20 already has
added designated initializers and this should be able to build on that.
Syntax rules:
Within an aggregate initialization while the rest operator (...) is
encountered at the beginning of a list (in the same place a designatede
initializer would be) the ... is expected to be followed by an value that
is the source value to pick members from, the compiler should allow for
multiple source values.
AFTER the last rest operator has been found there can only be additional
designated initializers.
(Putting spreads after designated initializers makes little sense if
following the semantics below)
IE:
T object * {* *.*designator *=* arg1 *,* *.*designator *{* arg2 *} *... *};*
would become
T object * {* ...sarg1, ...sarg2 , <SNIP> *.*designator *=* darg1 *,* *.*
designator *{* darg2 *} *<SNIP> *};*
(<SNIP> is used above since ... would be ambigious in this case)
sarg1, sarg2 are source objects whilst darg1 and darg2 are direct values.
Semantics:
The compiler should expand all members from each source arg(sarg) in
left-to-right order, the expanded members if overridden by other spreads or
explicitly given designated initializers should be ignored.
The spreading should occur on a visible OR public per-name basis, thus a
source-arg need not be of the same type as the object being initialized and
multiple objects of different types can be used to initialize one
destination object.
Spreading a member that does not exist in the destination must not be
allowed.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/618d7960-6f9e-447d-9020-adc06a67652a%40isocpp.org.
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/618d7960-6f9e-447d-9020-adc06a67652a%40isocpp.org.