Topic: Better DRY when initializing members in constructor


Author: Raymund Hofmann <hofmannraymund@gmail.com>
Date: Sun, 20 May 2018 22:53:02 -0700 (PDT)
Raw View
------=_Part_26242_2137733184.1526881982429
Content-Type: multipart/alternative;
 boundary="----=_Part_26243_843672496.1526881982429"

------=_Part_26243_843672496.1526881982429
Content-Type: text/plain; charset="UTF-8"

initializing members via the constructor repeats the type two times plus a
variable name three times:

struct S
{
    int i;
    const char* cp;
    S(int i, const char* cp) : i(i), cp(cp) {}
};

I was trying to find a way improving on this.

The best i could come up with was something like:

struct T
{
    struct I
    {
        int i;
        const char* cp;
    } m;
    T(const I& i) : m(i) {}
};

usage:

void testf()
{
    S s(1, "abc");
    T t({ 1,"abc" });
}

Are there already some proposals/ideas for improving DRY on this?

My Idea:

I could think of a different class definition something like "lambda
capture style":

struct U (i=int(0); *cp="123") // <- "capture list"
{
  // members which are initialized to a fixed value don't go in the
"capture list", use regular members
  // capture list generates a constructor to initialize the members implied
by the "capture list"
  // usual class members/functions go here...
};

usage:

void testf()
{
  U u(3,{});
}

The generated constructor should also be available to delegate to, so
additional constructors can be had if desired.
Maybe there is a better idea for integrating this "capture style"
initialization nicer and more compact when using it as a delegate.

--
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/cd751fc2-11ab-4e7c-b90e-5045f7df2c5c%40isocpp.org.

------=_Part_26243_843672496.1526881982429
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">initializing members via the constructor repeats the type =
two times plus a variable name three times:<br><br><span style=3D"font-fami=
ly: courier\ new, monospace;">struct S<br>{<br>=C2=A0=C2=A0=C2=A0 int i;<br=
>=C2=A0=C2=A0=C2=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 S(int i, const ch=
ar* cp) : i(i), cp(cp) {}<br>};<br><br></span>I was trying to find a way im=
proving on this.<br><br>The best i could come up with was something like:<b=
r><br><span style=3D"font-family: courier\ new, monospace;">struct T<br>{<b=
r>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 const c=
har* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=A0=C2=A0=C2=A0 T(const I&amp; i)=
 : m(i) {}<br>};<br><br></span>usage:<br><br><span style=3D"font-family: co=
urier\ new, monospace;">void testf()<br>{<br>=C2=A0=C2=A0=C2=A0 S s(1, &quo=
t;abc&quot;);<br>=C2=A0=C2=A0=C2=A0 T t({ 1,&quot;abc&quot; });<br>}<br><br=
><span style=3D"font-family: arial, sans-serif;">Are there already some pro=
posals/ideas for improving DRY on this?<br><br>My Idea:<br><br>I could thin=
k of a different class definition something like &quot;lambda capture style=
&quot;:<br><br></span>struct U (i=3Dint(0); *cp=3D&quot;123&quot;) // &lt;-=
 &quot;capture list&quot;<br>{<br>=C2=A0 // members which are initialized t=
o a fixed value don&#39;t go in the &quot;capture list&quot;, use regular m=
embers<br>=C2=A0 // capture list generates a constructor to initialize the =
members implied by the &quot;capture list&quot;<br>=C2=A0 // usual class me=
mbers/functions go here...<br>};<br><br><span style=3D"font-family: arial, =
sans-serif;">usage:</span><br><br>void testf()<br>{<br>=C2=A0 U u(3,{});<br=
>}<br><br><span style=3D"font-family: arial, sans-serif;">The generated con=
structor should also be available to delegate to, so additional constructor=
s can be had if desired.<br>Maybe there is a better idea for integrating th=
is &quot;capture style&quot; initialization nicer and more compact when usi=
ng it as a delegate.</span><br></span></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cd751fc2-11ab-4e7c-b90e-5045f7df2c5c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cd751fc2-11ab-4e7c-b90e-5045f7df2c5c=
%40isocpp.org</a>.<br />

------=_Part_26243_843672496.1526881982429--

------=_Part_26242_2137733184.1526881982429--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Mon, 21 May 2018 09:07:48 +0200
Raw View
On Sun, May 20, 2018 at 10:53:02PM -0700, Raymund Hofmann wrote:
> initializing members via the constructor repeats the type two times plus a
> variable name three times:
>
> struct S
> {
>     int i;
>     const char* cp;
>     S(int i, const char* cp) : i(i), cp(cp) {}
> };
>
> I was trying to find a way improving on this.
>
> The best i could come up with was something like:
>
> struct T
> {
>     struct I
>     {
>         int i;
>         const char* cp;
>     } m;
>     T(const I& i) : m(i) {}
> };
>
> usage:
>
> void testf()
> {
>     S s(1, "abc");
>     T t({ 1,"abc" });
> }
>
> Are there already some proposals/ideas for improving DRY on this?
>
> My Idea:
>
> I could think of a different class definition something like "lambda
> capture style":
>
> struct U (i=int(0); *cp="123") // <- "capture list"
> {
>   // members which are initialized to a fixed value don't go in the
> "capture list", use regular members
>   // capture list generates a constructor to initialize the members implied
> by the "capture list"
>   // usual class members/functions go here...
> };
>
> usage:
>
> void testf()
> {
>   U u(3,{});
> }
>
> The generated constructor should also be available to delegate to, so
> additional constructors can be had if desired.
> Maybe there is a better idea for integrating this "capture style"
> initialization nicer and more compact when using it as a delegate.
>

In C++-14 you can write

struct V
{
        int i = 0;
        const char* cp = "123";
};

V v1;
V v2 { 2, "234" };

Is that terse enough for you?

/MF

--
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/20180521070748.GA3811%40noemi.bahnhof.se.

.


Author: Raymund Hofmann <hofmannraymund@gmail.com>
Date: Mon, 21 May 2018 00:23:18 -0700 (PDT)
Raw View
------=_Part_26791_883090159.1526887398883
Content-Type: multipart/alternative;
 boundary="----=_Part_26792_1421355074.1526887398883"

------=_Part_26792_1421355074.1526887398883
Content-Type: text/plain; charset="UTF-8"

I am aware of that, In my example you can see i already used what you
propose in a slightly more indirect way, because it has limitations:

struct T
{
    struct I
    {
        int i;
        const char* cp;
    } m;
    T(const I& i) : m(i) {}
};

usage:

void testf()
{
    T t({ 1,"abc" });
}

I chose this way because if you inherit for example from std::
enable_shared_from_this, you lose the ability to initialize members in the
way you have shown, you are required to have a constructor then:

struct TS : std::enable_shared_from_this<T>
{
    struct I
    {
        int i;
        const char* cp;
    } m;
    //TS(const I& i) : m(i) {}
};

TS ts{ 1,"abc" }; // error

even worse, when you create a object with make_shared like so:

struct TS : std::enable_shared_from_this<T>
{
    struct I
    {
        int i;
        const char* cp;
    } m;
    TS(const I& i) : m(i) {}
};

void testf()
{
    auto so = std::make_shared<T>(TS::I{ 1,"abc" });
}

You have to repeat I defined in TS, or alternatively write a constructor
which needs too much repetition as mentioned.


--
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/1bc6ebbe-4d52-40b7-9e06-d096e76631ba%40isocpp.org.

------=_Part_26792_1421355074.1526887398883
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><span style=3D"font-family: arial, sans-serif;">I am aware=
 of that, In my example you can see i already used what you propose in a sl=
ightly more indirect way, because it has limitations:<br><br><span>struct T=
<br>{<br>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=
=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=A0=C2=A0=C2=A0 T(cons=
t I&amp; i) : m(i) {}<br>};<br><br></span>usage:<br><br><span>void testf()<=
br>{<br>=C2=A0=C2=A0=C2=A0 T t({ 1,&quot;abc&quot; });<br>}<br><br>I chose =
this way because if you inherit for example from</span><span style=3D"font-=
size:0.7em; line-height:130%"> std::</span>enable_shared_from_this<span>, y=
ou lose the ability to initialize members in the way you have shown, you ar=
e required to have a constructor then:<br><br>struct TS : std::enable_share=
d_from_this&lt;T&gt;<br>{<br>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=A0=C2=
=A0 {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=A0=C2=
=A0=C2=A0 //TS(const I&amp; i) : m(i) {}<br>};<br><br>TS ts{ 1,&quot;abc&qu=
ot; }; // error<br><br>even worse, when you create a object with make_share=
d like so:<br><br>struct TS : std::enable_shared_from_this&lt;T&gt;<br>{<br=
>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 =
=C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 const ch=
ar* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=A0=C2=A0=C2=A0 TS(const I&amp; i)=
 : m(i) {}<br>};<br><br>void testf()<br>{<br>=C2=A0=C2=A0=C2=A0 auto so =3D=
 std::make_shared&lt;T&gt;(TS::I{ 1,&quot;abc&quot; });<br>}<br><br>You hav=
e to repeat I defined in TS, or alternatively write a constructor which nee=
ds too much repetition as mentioned.<br><br><br></span></span></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1bc6ebbe-4d52-40b7-9e06-d096e76631ba%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1bc6ebbe-4d52-40b7-9e06-d096e76631ba=
%40isocpp.org</a>.<br />

------=_Part_26792_1421355074.1526887398883--

------=_Part_26791_883090159.1526887398883--

.


Author: Alberto Barbati <albertobarbati@gmail.com>
Date: Tue, 22 May 2018 02:34:33 -0700 (PDT)
Raw View
------=_Part_34310_1407050665.1526981673621
Content-Type: multipart/alternative;
 boundary="----=_Part_34311_1627748336.1526981673621"

------=_Part_34311_1627748336.1526981673621
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable


Il giorno luned=C3=AC 21 maggio 2018 09:23:18 UTC+2, Raymund Hofmann ha scr=
itto:
>
> I chose this way because if you inherit for example from std::
> enable_shared_from_this, you lose the ability to initialize members in=20
> the way you have shown, you are required to have a constructor then:
>
> struct TS : std::enable_shared_from_this<T>
> {
>     struct I
>     {
>         int i;
>         const char* cp;
>     } m;
>     //TS(const I& i) : m(i) {}
> };
>
> TS ts{ 1,"abc" }; // error
>

But that's only because std::enable_shared_from_this has a protected=20
constructor. If it had a public constructor you would be able to write this=
:

    TS ts{ {}, 1,"abc" };

Frankly, this example is not very compelling, as it is burdened with an=20
unrelated issue (the access control of the protected ctor). It seems to me=
=20
that you are proposing a whole new syntax to solve a very narrow problem.=
=20
If you at least could provide a better example...

--=20
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 e=
mail 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/d92647a5-4a82-41a0-bbc2-173663f01b11%40isocpp.or=
g.

------=_Part_34311_1627748336.1526981673621
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>Il giorno luned=C3=AC 21 maggio 2018 09:23:18 UTC+2, R=
aymund Hofmann ha scritto:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><span style=3D"font-family:arial,sans-serif"><span>I chose thi=
s way because if you inherit for example from</span><span style=3D"font-siz=
e:0.7em;line-height:130%"> std::</span>enable_shared_from_this<span>, you l=
ose the ability to initialize members in the way you have shown, you are re=
quired to have a constructor then:<br><br>struct TS : std::enable_shared_fr=
om_this&lt;<wbr>T&gt;<br>{<br>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=A0=
=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=C2=
=A0 =C2=A0=C2=A0=C2=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=A0=
=C2=A0=C2=A0 //TS(const I&amp; i) : m(i) {}<br>};<br><br>TS ts{ 1,&quot;abc=
&quot; }; // error<br></span></span></div></blockquote><div><br></div><div>=
But that&#39;s only because std::enable_shared_from_this has a protected co=
nstructor. If it had a public constructor you would be able to write this:<=
/div><div><br></div><div><span style=3D"font-family:arial,sans-serif"><span=
>=C2=A0=C2=A0=C2=A0 TS ts{ {}, 1,&quot;abc&quot; };</span></span></div><div=
><br> </div><div>Frankly, this example is not very compelling, as it is bur=
dened with an unrelated issue (the access control of the protected ctor). I=
t seems to me that you are proposing a whole new syntax to solve a very nar=
row problem. If you at least could provide a better example...<br></div></d=
iv>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d92647a5-4a82-41a0-bbc2-173663f01b11%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d92647a5-4a82-41a0-bbc2-173663f01b11=
%40isocpp.org</a>.<br />

------=_Part_34311_1627748336.1526981673621--

------=_Part_34310_1407050665.1526981673621--

.


Author: Viacheslav Usov <via.usov@gmail.com>
Date: Thu, 24 May 2018 12:28:43 +0200
Raw View
--000000000000a3bcc1056cf11df4
Content-Type: text/plain; charset="UTF-8"

On Mon, May 21, 2018 at 7:53 AM, Raymund Hofmann <hofmannraymund@gmail.com>
wrote:

> Are there already some proposals/ideas for improving DRY on this?

The entire issue arises when some members have to be initialised in a
pass-through fashion, while the others in some other way. In the most
general case, you might have different constructors with different sets of
the pass-through parameters, and you cannot choose a preferred constructor.
In this most general case, an obvious idea is that you say right in the
constructor's parameter list that "this one is passed through", e.g.: S::S(
=i, =cp ) {} This entire syntax is just an illustration..

The most general approach repeats the name of the pass-through member for
each such constructor; it also repeats the name of the class once per
constructor. Frankly, repeating the class name is ugly and has always been
even irrespective of this entire issue, so we might consider an
abbreviation for that (and destructors, for good measure). For example, the
constructor can be abbreviated to :=(parameter list): init list {body} and
the destructor to [virtual] :~() {body} (again purely an illustration, but
:= and :~ unlike some other candidates would make it easy to grep for these
special members).

So now we are down to one pass-through member repetition per constructor. I
do not think it is possible to do better than this unless the problem is
constrained further.

struct S
{
    int a;
    const char *b";

    :=(=a) : b("123") {}
    :=(=b) : a(1) {}
};

S(2), S("456");

Cheers,
V.

--
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/CAA7YVg0akQ%2BZNcknomtdMGLrjYvaA_dkkL-9W_X9KtGy1Dxw%3DQ%40mail.gmail.com.

--000000000000a3bcc1056cf11df4
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, May 21, 2018 at 7:53 AM, Raymund Hofmann <span dir=3D"ltr">&lt;<a href=
=3D"mailto:hofmannraymund@gmail.com" target=3D"_blank">hofmannraymund@gmail=
..com</a>&gt;</span> wrote:<br><div><br></div><div>&gt; Are there already so=
me proposals/ideas for improving DRY on this?</div><div><br></div><div>The =
entire issue arises when some members have to be initialised in a pass-thro=
ugh fashion, while the others in some other way. In the most general case, =
you might have different constructors with different sets of the pass-throu=
gh parameters, and you cannot choose a preferred constructor. In this most =
general case, an obvious idea is that you say right in the constructor&#39;=
s parameter list that &quot;this one is passed through&quot;, e.g.: S::S( =
=3Di, =3Dcp ) {} This entire syntax is just an illustration..</div><div><br=
></div><div>The most general approach repeats the name of the pass-through =
member for each such constructor; it also repeats the name of the class onc=
e per constructor. Frankly, repeating the class name is ugly and has always=
 been even irrespective of this entire issue, so we might consider an abbre=
viation for that (and destructors, for good measure). For example, the cons=
tructor can be abbreviated to :=3D(parameter list): init list {body} and th=
e destructor to [virtual] :~() {body} (again purely an illustration, but :=
=3D and :~ unlike some other candidates would make it easy to grep for thes=
e special members).</div><div><br></div><div>So now we are down to one pass=
-through member repetition per constructor. I do not think it is possible t=
o do better than this unless the problem is constrained further.</div><div>=
<br></div><div>struct S</div><div>{</div><div>=C2=A0 =C2=A0 int a;</div><di=
v>=C2=A0 =C2=A0 const char *b&quot;;</div><div><br></div><div>=C2=A0 =C2=A0=
 :=3D(=3Da) : b(&quot;123&quot;) {}</div><div>=C2=A0 =C2=A0 :=3D(=3Db) : a(=
1) {}</div><div>};</div><div><br></div><div>S(2), S(&quot;456&quot;);</div>=
<div><br></div><div>Cheers,</div><div>V.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAA7YVg0akQ%2BZNcknomtdMGLrjYvaA_dkkL=
-9W_X9KtGy1Dxw%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg0akQ%2=
BZNcknomtdMGLrjYvaA_dkkL-9W_X9KtGy1Dxw%3DQ%40mail.gmail.com</a>.<br />

--000000000000a3bcc1056cf11df4--

.


Author: mihailnajdenov@gmail.com
Date: Fri, 25 May 2018 08:32:12 -0700 (PDT)
Raw View
------=_Part_13652_1593050837.1527262332629
Content-Type: multipart/alternative;
 boundary="----=_Part_13653_1701983482.1527262332629"

------=_Part_13653_1701983482.1527262332629
Content-Type: text/plain; charset="UTF-8"

Well, I use the same approach for years.
The main downside is (outside extra moves/copies), you have to prefix the
members (cp becomes m.cp) which is quite unnatural

Interestingly the approach will become even more viable inC++20 with named
initializers

 T t({ .i=1, .cb="abc" });

In any case I also hope the situation can be improved, though no solution
will be perfect.

Google's Dart for instance has a neat shortcut in the form

S(this.i, this.cp)

which eliminates 2/3 of the repetition.

Probably something can be ported to C++

// declaration
S(.i, .cp);

// COMPILER GENERATED
S::S(int i, string cp)
: i(std::move(i))
, cb(std::move(cb))
{}

The user can define the ctor in the form of

S::S(.i, .cp)
{
  // use members i, use cp as ususal
}

On Monday, May 21, 2018 at 8:53:02 AM UTC+3, Raymund Hofmann wrote:
>
> initializing members via the constructor repeats the type two times plus a
> variable name three times:
>
> struct S
> {
>     int i;
>     const char* cp;
>     S(int i, const char* cp) : i(i), cp(cp) {}
> };
>
> I was trying to find a way improving on this.
>
> The best i could come up with was something like:
>
> struct T
> {
>     struct I
>     {
>         int i;
>         const char* cp;
>     } m;
>     T(const I& i) : m(i) {}
> };
>
> usage:
>
> void testf()
> {
>     S s(1, "abc");
>     T t({ 1,"abc" });
> }
>
> Are there already some proposals/ideas for improving DRY on this?
>
> My Idea:
>
> I could think of a different class definition something like "lambda
> capture style":
>
> struct U (i=int(0); *cp="123") // <- "capture list"
> {
>   // members which are initialized to a fixed value don't go in the
> "capture list", use regular members
>   // capture list generates a constructor to initialize the members
> implied by the "capture list"
>   // usual class members/functions go here...
> };
>
> usage:
>
> void testf()
> {
>   U u(3,{});
> }
>
> The generated constructor should also be available to delegate to, so
> additional constructors can be had if desired.
> Maybe there is a better idea for integrating this "capture style"
> initialization nicer and more compact when using it as a delegate.
>

--
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/55237820-447a-4e97-b503-c4550dfa0b15%40isocpp.org.

------=_Part_13653_1701983482.1527262332629
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Well, I use the same approach for years.=C2=A0</div><=
div>The main downside is (outside extra moves/copies), you have to prefix t=
he members (<font face=3D"courier new,monospace">cp <font face=3D"arial,san=
s-serif">becomes</font> m.cp) </font><font face=3D"arial,sans-serif">which =
is quite unnatural</font></div><div><br></div><div>Interestingly the approa=
ch will become even more viable inC++20 with named initializers</div><div><=
font face=3D"courier new,monospace"></font><br></div><div><font face=3D"cou=
rier new,monospace">=C2=A0<span style=3D"text-align: left; color: rgb(34, 3=
4, 34); text-transform: none; text-indent: 0px; letter-spacing: normal; fon=
t-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; t=
ext-decoration: none; word-spacing: 0px; display: inline !important; white-=
space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; bac=
kground-color: transparent;">T t({ .i=3D1, .cb=3D&quot;abc&quot; });</span>=
</font></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></stri=
ke><font face=3D"courier new,monospace"></font><br></div><div>In any case I=
 also hope the situation can be improved, though no solution will be perfec=
t.=C2=A0</div><div><br></div><div>Google&#39;s Dart for instance has a neat=
 shortcut in the form</div><div><br></div><div><span style=3D"text-align: l=
eft; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter=
-spacing: normal; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; text-decoration: none; word-spacing: 0px; display: inli=
ne !important; white-space: normal; orphans: 2; float: none; -webkit-text-s=
troke-width: 0px; background-color: transparent;"><font face=3D"courier new=
,monospace">S(this.i, this.cp)</font></span><b></b><i></i><u></u><sub></sub=
><sup></sup><strike></strike><br></div><div><b></b><i></i><u></u><sub></sub=
><sup></sup><strike></strike><font face=3D"courier new,monospace"></font><b=
r></div><div>which eliminates 2/3 of the repetition.=C2=A0</div><div><br></=
div><div>Probably something can be ported to C++</div><div><font face=3D"co=
urier new,monospace"></font><br></div><div><font face=3D"courier new,monosp=
ace">// declaration</font></div><div><span style=3D"background-color: trans=
parent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bo=
rder-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretc=
h; border-image-slice: 100%; border-image-source: none; border-image-width:=
 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-lef=
t-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none=
; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-st=
yle: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; =
float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp=
;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=
=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); b=
order-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0;=
 border-image-repeat: stretch; border-image-slice: 100%; border-image-sourc=
e: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-=
left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 3=
4); border-right-style: none; border-right-width: 0px; border-top-color: rg=
b(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">S(.i, .cp)=
;</font></span></div><div><br></div><div><font face=3D"courier new,monospac=
e">// COMPILER GENERATED</font></div><div><font face=3D"courier new,monospa=
ce">S::S(<span style=3D"text-align: left; color: rgb(34, 34, 34); text-tran=
sform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; fon=
t-style: normal; font-variant: normal; font-weight: 400; text-decoration: n=
one; word-spacing: 0px; display: inline !important; white-space: normal; or=
phans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: tr=
ansparent;">int i, string cp)</span></font></div><div><span style=3D"text-a=
lign: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px;=
 letter-spacing: normal; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; text-decoration: none; word-spacing: 0px; displa=
y: inline !important; white-space: normal; orphans: 2; float: none; -webkit=
-text-stroke-width: 0px; background-color: transparent;"><font face=3D"cour=
ier new,monospace">: i(std::move(i))</font></span></div><div><span style=3D=
"text-align: left; color: rgb(34, 34, 34); text-transform: none; text-inden=
t: 0px; letter-spacing: normal; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; text-decoration: none; word-spacing: 0px;=
 display: inline !important; white-space: normal; orphans: 2; float: none; =
-webkit-text-stroke-width: 0px; background-color: transparent;"><font face=
=3D"courier new,monospace">, cb<span style=3D"text-align: left; color: rgb(=
34, 34, 34); text-transform: none; text-indent: 0px; letter-spacing: normal=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; text-decoration: none; word-spacing: 0px; display: inline !important; w=
hite-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px=
; background-color: transparent;">(std::move(cb))</span></font></span></div=
><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-transfo=
rm: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; font-s=
tyle: normal; font-variant: normal; font-weight: 400; text-decoration: none=
; word-spacing: 0px; display: inline !important; white-space: normal; orpha=
ns: 2; float: none; -webkit-text-stroke-width: 0px; background-color: trans=
parent;"><font face=3D"courier new,monospace"><span style=3D"text-align: le=
ft; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-=
spacing: normal; font-size: 13px; font-style: normal; font-variant: normal;=
 font-weight: 400; text-decoration: none; word-spacing: 0px; display: inlin=
e !important; white-space: normal; orphans: 2; float: none; -webkit-text-st=
roke-width: 0px; background-color: transparent;">{}</span></font></span></d=
iv><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-trans=
form: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; font=
-style: normal; font-variant: normal; font-weight: 400; text-decoration: no=
ne; word-spacing: 0px; display: inline !important; white-space: normal; orp=
hans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: tra=
nsparent;"><font face=3D"courier new,monospace"><span style=3D"text-align: =
left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; lette=
r-spacing: normal; font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; text-decoration: none; word-spacing: 0px; display: inl=
ine !important; white-space: normal; orphans: 2; float: none; -webkit-text-=
stroke-width: 0px; background-color: transparent;"><br></span></font></span=
></div><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-t=
ransform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; =
font-style: normal; font-variant: normal; font-weight: 400; text-decoration=
: none; word-spacing: 0px; display: inline !important; white-space: normal;=
 orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-color:=
 transparent;"><span style=3D"text-align: left; color: rgb(34, 34, 34); tex=
t-transform: none; text-indent: 0px; letter-spacing: normal; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; text-decorat=
ion: none; word-spacing: 0px; display: inline !important; white-space: norm=
al; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-col=
or: transparent;"><font face=3D"arial,sans-serif">The user can define the c=
tor in the form of</font></span></span></div><div><br></div><div><font face=
=3D"courier new,monospace"><span style=3D"text-align: left; color: rgb(34, =
34, 34); text-transform: none; text-indent: 0px; letter-spacing: normal; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
text-decoration: none; word-spacing: 0px; display: inline !important; white=
-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; ba=
ckground-color: transparent;">S::S(</span><span style=3D"margin: 0px; paddi=
ng: 0px; border: 0px rgb(34, 34, 34); border-image: none; text-align: left;=
 color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-spa=
cing: normal; font-size: 13px; font-style: normal; font-variant: normal; fo=
nt-weight: 400; text-decoration: none; word-spacing: 0px; display: inline; =
white-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0p=
x; background-color: transparent;">.i, .cp)</span></font></div><div><font f=
ace=3D"courier new,monospace">{</font></div><div><font face=3D"courier new,=
monospace">=C2=A0 // use members i, use cp as ususal</font></div><div><font=
 face=3D"courier new,monospace">}</font></div><div><b></b><i></i><u></u><su=
b></sub><sup></sup><strike></strike><font face=3D"courier new,monospace"></=
font><br></div>On Monday, May 21, 2018 at 8:53:02 AM UTC+3, Raymund Hofmann=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">initia=
lizing members via the constructor repeats the type two times plus a variab=
le name three times:<br><br><span>struct S<br>{<br>=C2=A0=C2=A0=C2=A0 int i=
;<br>=C2=A0=C2=A0=C2=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 S(int i, cons=
t char* cp) : i(i), cp(cp) {}<br>};<br><br></span>I was trying to find a wa=
y improving on this.<br><br>The best i could come up with was something lik=
e:<br><br><span>struct T<br>{<br>=C2=A0=C2=A0=C2=A0 struct I<br>=C2=A0=C2=
=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 int i;<br>=C2=A0=C2=A0=
=C2=A0 =C2=A0=C2=A0=C2=A0 const char* cp;<br>=C2=A0=C2=A0=C2=A0 } m;<br>=C2=
=A0=C2=A0=C2=A0 T(const I&amp; i) : m(i) {}<br>};<br><br></span>usage:<br><=
br><span>void testf()<br>{<br>=C2=A0=C2=A0=C2=A0 S s(1, &quot;abc&quot;);<b=
r>=C2=A0=C2=A0=C2=A0 T t({ 1,&quot;abc&quot; });<br>}<br><br><span style=3D=
"font-family:arial,sans-serif">Are there already some proposals/ideas for i=
mproving DRY on this?<br><br>My Idea:<br><br>I could think of a different c=
lass definition something like &quot;lambda capture style&quot;:<br><br></s=
pan>struct U (i=3Dint(0); *cp=3D&quot;123&quot;) // &lt;- &quot;capture lis=
t&quot;<br>{<br>=C2=A0 // members which are initialized to a fixed value do=
n&#39;t go in the &quot;capture list&quot;, use regular members<br>=C2=A0 /=
/ capture list generates a constructor to initialize the members implied by=
 the &quot;capture list&quot;<br>=C2=A0 // usual class members/functions go=
 here...<br>};<br><br><span style=3D"font-family:arial,sans-serif">usage:</=
span><br><br>void testf()<br>{<br>=C2=A0 U u(3,{});<br>}<br><br><span style=
=3D"font-family:arial,sans-serif">The generated constructor should also be =
available to delegate to, so additional constructors can be had if desired.=
<br>Maybe there is a better idea for integrating this &quot;capture style&q=
uot; initialization nicer and more compact when using it as a delegate.</sp=
an><br></span></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/55237820-447a-4e97-b503-c4550dfa0b15%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/55237820-447a-4e97-b503-c4550dfa0b15=
%40isocpp.org</a>.<br />

------=_Part_13653_1701983482.1527262332629--

------=_Part_13652_1593050837.1527262332629--

.