Topic: Return this or *this in overridden method in child class?


Author: Vu Pham <phvu225@gmail.com>
Date: Fri, 30 Nov 2018 13:38:07 +0000
Raw View
--000000000000808653057be1e9a1
Content-Type: text/plain; charset="UTF-8"

While thinking about my (ahem) streaming proposal
<https://groups.google.com/a/isocpp.org/forum/?utm_medium=email&utm_source=footer#!msg/std-proposals/w0j1pF8gQPQ/YzHdodLoBwAJ>,
I think I found a missing feature in C++. Since this group is highly
populated with people speaking C++ fluently, I will ask this here instead.

Assume I have the following classes:

class A {
public:
    A& f1(float& x) {
        x++;
        return *this;
    }
};

class B: public A {
public:
    B& f2(float& x) {
        x--;
        return *this;
    }
};

int main()
{
    float x(100.0f);
    B b;
    *static_cast<B>(b.f1(x)).f2(x);*   // this doesn't compile
    return 0;
}

The idea is I want B::f1() to return an instance of B (it should, given the
implementation of f1), but since the return type of f1() is A&, apparently
there is no way to make it work the way I want. Here are a few alternatives
I tried:

- Make f1() returns A*, then cast the returned pointer. This doesn't look
really nice.
- Change the return type of f1() to something like decltype(*this) or auto,
none of this seems to work.

This issue may get worse if A and B are templated, or in a more complicated
scenario where A::f1() returns a child class C of A, while B is a child of
A but not C, and I want to override B::f1() to return D, which is a child
class of B.

Since C++ allows multiple inheritence, and in the same light with the
*concept* idea that are coming up in new C++, should we coin a new
annotation to indicate that a function returns an instance of *this* class?
The actual returned type will change depending on the actual type of the
class that mix those functions in.

What do you think?
Vu

--
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/CAFhKpXFOV9DSmmrC3HdGF7Fr44fRzpq%3Dn2JTkUcHHE6Qbux-PA%40mail.gmail.com.

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

<div dir=3D"ltr"><div dir=3D"ltr"><div>While thinking about my (ahem) <a hr=
ef=3D"https://groups.google.com/a/isocpp.org/forum/?utm_medium=3Demail&amp;=
utm_source=3Dfooter#!msg/std-proposals/w0j1pF8gQPQ/YzHdodLoBwAJ">streaming =
proposal</a>, I think I found a missing feature in C++. Since this group is=
 highly populated with people speaking C++ fluently, I will ask this here i=
nstead.</div><div><br></div><div>Assume I have the following classes:</div>=
<div><br></div><div><span style=3D"font-family:monospace,monospace">class A=
 {<br>public:<br>=C2=A0=C2=A0=C2=A0 A&amp; f1(float&amp; x) {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 x++;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 return *this;<br>=C2=A0=C2=A0=C2=A0 }<br>};<br><br>class B: publi=
c A {<br>public:<br>=C2=A0=C2=A0=C2=A0 B&amp; f2(float&amp; x) {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 x--;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 return *this;<br>=C2=A0=C2=A0=C2=A0 }<br>};<br><br>int main()<=
br>{<br>=C2=A0=C2=A0=C2=A0 float x(100.0f);<br>=C2=A0=C2=A0=C2=A0 B b;<br>=
=C2=A0=C2=A0=C2=A0 <b>static_cast&lt;B&gt;(b.f1(x)).f2(x);</b>=C2=A0=C2=A0 =
// this doesn&#39;t compile<br>=C2=A0=C2=A0=C2=A0 return 0;<br>}</span><br>=
</div><div><br></div><div>The idea is I want B::f1() to return an instance =
of B (it should, given the implementation of f1), but since the return type=
 of f1() is A&amp;, apparently there is no way to make it work the way I wa=
nt. Here are a few alternatives I tried:</div><div><br></div><div>- Make f1=
() returns A*, then cast the returned pointer. This doesn&#39;t look really=
 nice.</div><div>- Change the return type of f1() to something like decltyp=
e(*this) or auto, none of this seems to work.</div><div><br></div><div>This=
 issue may get worse if A and B are templated, or in a more complicated sce=
nario where A::f1() returns a child class C of A, while B is a child of A b=
ut not C, and I want to override B::f1() to return D, which is a child clas=
s of B.</div><div><br></div><div>Since C++ allows multiple inheritence, and=
 in the same light with the <i>concept</i> idea that are coming up in new C=
++, should we coin a new annotation to indicate that a function returns an =
instance of <i>this</i> class? The actual returned type will change dependi=
ng on the actual type of the class that mix those functions in.</div><div><=
br></div><div>What do you think?</div><div>Vu<br></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/CAFhKpXFOV9DSmmrC3HdGF7Fr44fRzpq%3Dn2=
JTkUcHHE6Qbux-PA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFhKpXFOV9DSmm=
rC3HdGF7Fr44fRzpq%3Dn2JTkUcHHE6Qbux-PA%40mail.gmail.com</a>.<br />

--000000000000808653057be1e9a1--

.