Topic: CRTP access


Author: David Krauss <potswa@gmail.com>
Date: Sat, 14 Jun 2014 12:38:25 +0800
Raw View
--Apple-Mail=_E4882F40-EF30-4144-905B-378B60849E39
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

A CRTP base class must either be publicly inherited, or friended, so that w=
ithin its own context the base is an accessible base of the derived class. =
Otherwise, the critical base-to-derived "downcast" is ill-formed.

Public inheritance is inappropriate unless the CRTP mixin is a public inter=
face.

Friending is inappropriate unless the CRTP mixin should access non-public m=
embers. It adds boilerplate. Worst, it's impossible in multi-level CRTP: th=
e derived class must know the specific base wanting friendship. Like many c=
ases of friendship, it fundamentally violates encapsulation.

What could be done to make a base accessible to itself from derived classes=
? This is the reciprocal of protected inheritance.

I wonder, what harm could come of granting access to every base class subob=
ject of every class within its own scope?

struct b {
    struct bn {
        template< typename d >
        static void foo( d & o ) {
            static_cast< b & >( o );
        }
    };
};

struct d : private b {} od;

b::bn::foo( od ); // Why not? b already presumes d::b exists and bn is just=
 part of b.

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_E4882F40-EF30-4144-905B-378B60849E39
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dus-ascii"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode=
: space; -webkit-line-break: after-white-space;"><div><div>A CRTP base clas=
s must either be publicly inherited, or friended, so that within its own co=
ntext the base is an accessible base of the derived class. Otherwise, the c=
ritical base-to-derived "downcast" is ill-formed.</div><div><br></div><div>=
Public inheritance is inappropriate unless the CRTP mixin is a public inter=
face.</div><div><br></div><div>Friending is inappropriate unless the CRTP m=
ixin should access non-public members. It adds boilerplate. Worst, it's imp=
ossible in multi-level CRTP: the derived class must know the specific base =
wanting friendship. Like many cases of friendship, it fundamentally violate=
s encapsulation.</div><div><br></div><div>What could be done to make a base=
 accessible to itself from derived classes? This is the reciprocal of prote=
cted inheritance.</div><div><br></div><div>I wonder, what harm could come o=
f granting access to every base class subobject of every class within its o=
wn scope?</div></div><div><br></div><div><font face=3D"Courier">struct b {<=
/font></div><div><font face=3D"Courier">&nbsp; &nbsp; struct bn {</font></d=
iv><div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &nbsp; template&lt; typ=
ename d &gt;</font></div><div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &=
nbsp; static void foo( d &amp; o ) {</font></div><div><font face=3D"Courier=
">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; static_cast&lt; b &amp; &gt;( o=
 );</font></div><div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &nbsp; }</=
font></div><div><font face=3D"Courier">&nbsp; &nbsp; };</font></div><div><f=
ont face=3D"Courier">};</font></div><div><font face=3D"Courier"><br></font>=
</div><div><font face=3D"Courier">struct d : private b {} od;</font></div><=
div><font face=3D"Courier"><br></font></div><div><font face=3D"Courier">b::=
bn::foo( od ); // Why not? b already presumes d::b exists and bn is just pa=
rt of b.</font></div><div><br></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_E4882F40-EF30-4144-905B-378B60849E39--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 14 Jun 2014 15:36:26 +0300
Raw View
On 14 June 2014 07:38, David Krauss <potswa@gmail.com> wrote:
> A CRTP base class must either be publicly inherited, or friended, so that
> within its own context the base is an accessible base of the derived class.
> Otherwise, the critical base-to-derived "downcast" is ill-formed.
>
> Public inheritance is inappropriate unless the CRTP mixin is a public
> interface.
>
> Friending is inappropriate unless the CRTP mixin should access non-public
> members. It adds boilerplate. Worst, it's impossible in multi-level CRTP:
> the derived class must know the specific base wanting friendship. Like many
> cases of friendship, it fundamentally violates encapsulation.
>
> What could be done to make a base accessible to itself from derived classes?
> This is the reciprocal of protected inheritance.
>
> I wonder, what harm could come of granting access to every base class
> subobject of every class within its own scope?

The harm is that a derived class that inherits a base B privately is-not-a-B,
the only classes that can convert derived to B is derived itself and
its friends,
and sure as hell downcasting B to derived makes little sense if derived inherits
B privately.

I can easily find a way to do CRTP with non-public bases: add a virtual function
to B that returns T*, and have derived classes override it. Example:

#include <iostream>
template <class T> struct B
{
    virtual T* pretty_please() = 0;
    void f() {pretty_please()->g();}
};

struct D : private B<D>
{
    D* pretty_please() override {return this;}
    void g() {std::cout << "D::b" << std::endl;}
    void h() {f();}
};

int main()
{
    D d;
    d.h();
}

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 14 Jun 2014 23:04:48 +0800
Raw View
--Apple-Mail=_E19EEC33-6709-4552-A300-83E0D86C218E
Content-Type: text/plain; charset=ISO-8859-1


On 2014-06-14, at 8:36 PM, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:

> The harm is that a derived class that inherits a base B privately is-not-a-B,
> the only classes that can convert derived to B is derived itself and
> its friends,

That simply states the rule in question.

> and sure as hell downcasting B to derived makes little sense if derived inherits
> B privately.

If B inherently knows itself to be a base of D, then it's not really very private. In CRTP the inheritance information is passed explicitly through the template parameter, so there's no secret to keep.

I'm not suggesting to open all of D to B, but only to expose the base class subobject *to itself*.

> I can easily find a way to do CRTP with non-public bases: add a virtual function
> to B that returns T*, and have derived classes override it. Example:

No way. Avoiding virtual dispatch is a main advantage of CRTP.

If it can be done with such a "dynamic downcast," why not support a more efficient semantic equivalent?

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_E19EEC33-6709-4552-A300-83E0D86C218E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;06&ndash;14, at 8:36 PM, Ville Voutilainen &lt;<a href=3D"mailto:vill=
e.voutilainen@gmail.com">ville.voutilainen@gmail.com</a>&gt; wrote:</div><b=
r class=3D"Apple-interchange-newline"><blockquote type=3D"cite">The harm is=
 that a derived class that inherits a base B privately is-not-a-B,<br>the o=
nly classes that can convert derived to B is derived itself and<br>its frie=
nds,<br></blockquote><div><br></div><div>That simply states the rule in que=
stion.</div><br><blockquote type=3D"cite">and sure as hell downcasting B to=
 derived makes little sense if derived inherits<br>B privately.<br></blockq=
uote><div><br></div><div>If B inherently knows itself to be a base of D, th=
en it&rsquo;s not really very private. In CRTP the inheritance information =
is passed explicitly through the template parameter, so there&rsquo;s no se=
cret to keep.</div><div><br></div><div>I&rsquo;m not suggesting to open all=
 of D to B, but only to expose the base class subobject *<i>to itself</i>*.=
</div><br><blockquote type=3D"cite">I can easily find a way to do CRTP with=
 non-public bases: add a virtual function<br>to B that returns T*, and have=
 derived classes override it. Example:<br></blockquote><div><br></div><div>=
No way. Avoiding virtual dispatch is a main advantage of CRTP.</div></div><=
br><div>If it can be done with such a &ldquo;dynamic downcast,&rdquo; why n=
ot support a more efficient semantic equivalent?</div><div><br></div></body=
></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_E19EEC33-6709-4552-A300-83E0D86C218E--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 14 Jun 2014 23:57:18 +0300
Raw View
On 14 June 2014 18:04, David Krauss <potswa@gmail.com> wrote:
> On 2014=E2=80=9306=E2=80=9314, at 8:36 PM, Ville Voutilainen <ville.vouti=
lainen@gmail.com>
> wrote:
> The harm is that a derived class that inherits a base B privately
> is-not-a-B,
> the only classes that can convert derived to B is derived itself and
> its friends,
> That simply states the rule in question.

The "rule in question" doesn't talk about a higher-level design concept whi=
ch
"is-a" represents.

>
> and sure as hell downcasting B to derived makes little sense if derived
> inherits
> B privately.
>
>
> If B inherently knows itself to be a base of D, then it=E2=80=99s not rea=
lly very

B doesn't "inherently know" that it happens to be a base of its template
argument.

> private. In CRTP the inheritance information is passed explicitly through
> the template parameter, so there=E2=80=99s no secret to keep.

Except the secrets D keeps by design - it's not a B, and it's not convertib=
le
from B nor to B. Base classes do not get special treatment and can't subver=
t
the access control of derived classes any more than any other classes can.

> I=E2=80=99m not suggesting to open all of D to B, but only to expose the =
base class
> subobject *to itself*.

I don't know that that's supposed to mean.

>
> I can easily find a way to do CRTP with non-public bases: add a virtual
> function
> to B that returns T*, and have derived classes override it. Example:
> No way. Avoiding virtual dispatch is a main advantage of CRTP.

You don't have to perform that virtual dispatch on every call. Alternativel=
y,
you can pass the pointer to the derived object up to the base.

> If it can be done with such a =E2=80=9Cdynamic downcast,=E2=80=9D why not=
 support a more
> efficient semantic equivalent?


Because it breaks design exceptions without sufficient motivation to do so?

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Sat, 14 Jun 2014 15:06:01 -0700
Raw View
--001a11334c38dd588304fbd2ffc6
Content-Type: text/plain; charset=UTF-8

On Sat, Jun 14, 2014 at 5:36 AM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:

> On 14 June 2014 07:38, David Krauss <potswa@gmail.com> wrote:
> > A CRTP base class must either be publicly inherited, or friended, so that
> > within its own context the base is an accessible base of the derived
> class.
> > Otherwise, the critical base-to-derived "downcast" is ill-formed.
> >
> > Public inheritance is inappropriate unless the CRTP mixin is a public
> > interface.
> >
> > Friending is inappropriate unless the CRTP mixin should access non-public
> > members. It adds boilerplate. Worst, it's impossible in multi-level CRTP:
> > the derived class must know the specific base wanting friendship. Like
> many
> > cases of friendship, it fundamentally violates encapsulation.
> >
> > What could be done to make a base accessible to itself from derived
> classes?
> > This is the reciprocal of protected inheritance.
> >
> > I wonder, what harm could come of granting access to every base class
> > subobject of every class within its own scope?
>
> The harm is that a derived class that inherits a base B privately
> is-not-a-B,
> the only classes that can convert derived to B is derived itself and
> its friends,
> and sure as hell downcasting B to derived makes little sense if derived
> inherits
> B privately.
>
> I can easily find a way to do CRTP with non-public bases: add a virtual
> function
> to B that returns T*, and have derived classes override it.


Or use a C-style cast from T* to B*. C-style derived-to-base casts ignore
whether the base class is accessible (see [expr.cast]p4).


> Example:
>
> #include <iostream>
> template <class T> struct B
> {
>     virtual T* pretty_please() = 0;
>     void f() {pretty_please()->g();}
> };
>
> struct D : private B<D>
> {
>     D* pretty_please() override {return this;}
>     void g() {std::cout << "D::b" << std::endl;}
>     void h() {f();}
> };
>
> int main()
> {
>     D d;
>     d.h();
> }
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11334c38dd588304fbd2ffc6
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 S=
at, Jun 14, 2014 at 5:36 AM, Ville Voutilainen <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilaine=
n@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"">On 14 June 2014 07:38, David=
 Krauss &lt;<a href=3D"mailto:potswa@gmail.com">potswa@gmail.com</a>&gt; wr=
ote:<br>

&gt; A CRTP base class must either be publicly inherited, or friended, so t=
hat<br>
&gt; within its own context the base is an accessible base of the derived c=
lass.<br>
&gt; Otherwise, the critical base-to-derived &quot;downcast&quot; is ill-fo=
rmed.<br>
&gt;<br>
&gt; Public inheritance is inappropriate unless the CRTP mixin is a public<=
br>
&gt; interface.<br>
&gt;<br>
&gt; Friending is inappropriate unless the CRTP mixin should access non-pub=
lic<br>
&gt; members. It adds boilerplate. Worst, it&#39;s impossible in multi-leve=
l CRTP:<br>
&gt; the derived class must know the specific base wanting friendship. Like=
 many<br>
&gt; cases of friendship, it fundamentally violates encapsulation.<br>
&gt;<br>
&gt; What could be done to make a base accessible to itself from derived cl=
asses?<br>
&gt; This is the reciprocal of protected inheritance.<br>
&gt;<br>
&gt; I wonder, what harm could come of granting access to every base class<=
br>
&gt; subobject of every class within its own scope?<br>
<br>
</div>The harm is that a derived class that inherits a base B privately is-=
not-a-B,<br>
the only classes that can convert derived to B is derived itself and<br>
its friends,<br>
and sure as hell downcasting B to derived makes little sense if derived inh=
erits<br>
B privately.<br>
<br>
I can easily find a way to do CRTP with non-public bases: add a virtual fun=
ction<br>
to B that returns T*, and have derived classes override it.</blockquote><di=
v><br></div><div>Or use a C-style cast from T* to B*. C-style derived-to-ba=
se casts ignore whether the base class is accessible (see [expr.cast]p4).</=
div>
<div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">Example:<br>
<br>
#include &lt;iostream&gt;<br>
template &lt;class T&gt; struct B<br>
{<br>
=C2=A0 =C2=A0 virtual T* pretty_please() =3D 0;<br>
=C2=A0 =C2=A0 void f() {pretty_please()-&gt;g();}<br>
};<br>
<br>
struct D : private B&lt;D&gt;<br>
{<br>
=C2=A0 =C2=A0 D* pretty_please() override {return this;}<br>
=C2=A0 =C2=A0 void g() {std::cout &lt;&lt; &quot;D::b&quot; &lt;&lt; std::e=
ndl;}<br>
=C2=A0 =C2=A0 void h() {f();}<br>
};<br>
<br>
int main()<br>
{<br>
=C2=A0 =C2=A0 D d;<br>
=C2=A0 =C2=A0 d.h();<br>
<div class=3D"HOEnZb"><div class=3D"h5">}<br>
<br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11334c38dd588304fbd2ffc6--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 15 Jun 2014 11:17:28 +0800
Raw View
--Apple-Mail=_DF3D8259-96F8-4C37-836E-1D85C461E6A7
Content-Type: text/plain; charset=ISO-8859-1


On 2014-06-15, at 6:06 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> Or use a C-style cast from T* to B*. C-style derived-to-base casts ignore whether the base class is accessible (see [expr.cast]p4).

Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code comment, and the language would probably benefit from CRTP-specific access specifiers, but the problem just got smaller.

(For folks following along, C casts degenerate to reinterpret_cast when the target is not in the inheritance hierarchy, so a static_assert on std::is_base_of, which also ignores accessibility, adds significant safety.)

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_DF3D8259-96F8-4C37-836E-1D85C461E6A7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/html cha=
rset=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/html=
 charset=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/=
html charset=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"t=
ext/html charset=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=
=3D"text/html charset=3Dwindows-1252"></head><body style=3D"word-wrap: brea=
k-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><=
div><br></div><div><div><div>On 2014&ndash;06&ndash;15, at 6:06 AM, Richard=
 Smith &lt;<a href=3D"mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</=
a>&gt; wrote:</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra"><div class=3D"gmail_quote">Or use a C-style cast from T* =
to B*. C-style derived-to-base casts ignore whether the base class is acces=
sible (see [expr.cast]p4).</div></div></div></blockquote><br></div><div>Ah,=
 thanks! I forgot this. Fits perfectly. Certainly needs a code comment, and=
 the language would probably benefit from CRTP-specific access specifiers, =
but the problem just got smaller.</div><div><br></div><div>(For folks follo=
wing along, C casts degenerate to <font face=3D"Courier">reinterpret_cast</=
font>&nbsp;when the target is not in the inheritance hierarchy, so a <font =
face=3D"Courier">static_assert</font> on&nbsp;<font face=3D"Courier">std::i=
s_base_of</font>, which also ignores accessibility, adds significant safety=
..)</div><div><br></div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_DF3D8259-96F8-4C37-836E-1D85C461E6A7--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 15 Jun 2014 05:35:52 -0700 (PDT)
Raw View
------=_Part_843_4165568.1402835752754
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

This wont be UB and only work when this class is first of base classes?

On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:
>
>
> On 2014=E2=80=9306=E2=80=9315, at 6:06 AM, Richard Smith <ric...@metafoo.=
co.uk=20
> <javascript:>> wrote:
>
> Or use a C-style cast from T* to B*. C-style derived-to-base casts ignore=
=20
> whether the base class is accessible (see [expr.cast]p4).
>
>
> Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code comment=
,=20
> and the language would probably benefit from CRTP-specific access=20
> specifiers, but the problem just got smaller.
>
> (For folks following along, C casts degenerate to reinterpret_cast when=
=20
> the target is not in the inheritance hierarchy, so a static_assert on=20
> std::is_base_of, which also ignores accessibility, adds significant=20
> safety.)
>
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_843_4165568.1402835752754
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This wont be UB and only work when this class is first of =
base classes?<br><br>On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Kraus=
s wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wra=
p:break-word"><div><br></div><div><div><div>On 2014=E2=80=9306=E2=80=9315, =
at 6:06 AM, Richard Smith &lt;<a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"Hh8_dC4swQkJ" onmousedown=3D"this.href=3D'javascript:=
';return true;" onclick=3D"this.href=3D'javascript:';return true;">ric...@m=
etafoo.co.uk</a>&gt; wrote:</div><br><blockquote type=3D"cite"><div dir=3D"=
ltr"><div><div class=3D"gmail_quote">Or use a C-style cast from T* to B*. C=
-style derived-to-base casts ignore whether the base class is accessible (s=
ee [expr.cast]p4).</div></div></div></blockquote><br></div><div>Ah, thanks!=
 I forgot this. Fits perfectly. Certainly needs a code comment, and the lan=
guage would probably benefit from CRTP-specific access specifiers, but the =
problem just got smaller.</div><div><br></div><div>(For folks following alo=
ng, C casts degenerate to <font face=3D"Courier">reinterpret_cast</font>&nb=
sp;when the target is not in the inheritance hierarchy, so a <font face=3D"=
Courier">static_assert</font> on&nbsp;<font face=3D"Courier">std::is_base_o=
f</font>, which also ignores accessibility, adds significant safety.)</div>=
<div><br></div></div></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_843_4165568.1402835752754--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 15 Jun 2014 21:33:10 +0800
Raw View
--Apple-Mail=_25584A7B-7921-4B6D-995D-6FBE1BF4E476
Content-Type: text/plain; charset=ISO-8859-1

No, the purpose of the static_assert I mentioned is to prevent reinterpret_cast from happening.

What we want is an access-bypassed static_cast semantic.


On 2014-06-15, at 8:35 PM, inkwizytoryankes@gmail.com wrote:

> This wont be UB and only work when this class is first of base classes?
>
> On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:
>
> On 2014-06-15, at 6:06 AM, Richard Smith <ric...@metafoo.co.uk> wrote:
>
>> Or use a C-style cast from T* to B*. C-style derived-to-base casts ignore whether the base class is accessible (see [expr.cast]p4).
>
> Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code comment, and the language would probably benefit from CRTP-specific access specifiers, but the problem just got smaller.
>
> (For folks following along, C casts degenerate to reinterpret_cast when the target is not in the inheritance hierarchy, so a static_assert on std::is_base_of, which also ignores accessibility, adds significant safety.)
>
>
> --
>
> ---
> 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.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_25584A7B-7921-4B6D-995D-6FBE1BF4E476
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><div>No, the purpose o=
f the static_assert I mentioned is to prevent reinterpret_cast from happeni=
ng.</div><div><br></div><div>What we want is an access-bypassed static_cast=
 semantic.</div><div><br></div><br><div><div>On 2014&ndash;06&ndash;15, at =
8:35 PM, <a href=3D"mailto:inkwizytoryankes@gmail.com">inkwizytoryankes@gma=
il.com</a> wrote:</div><br class=3D"Apple-interchange-newline"><blockquote =
type=3D"cite"><div dir=3D"ltr">This wont be UB and only work when this clas=
s is first of base classes?<br><br>On Sunday, June 15, 2014 5:17:56 AM UTC+=
2, David Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div sty=
le=3D"word-wrap:break-word"><div><br></div><div><div><div>On 2014&ndash;06&=
ndash;15, at 6:06 AM, Richard Smith &lt;<a href=3D"javascript:" target=3D"_=
blank" gdf-obfuscated-mailto=3D"Hh8_dC4swQkJ" onmousedown=3D"this.href=3D'j=
avascript:';return true;" onclick=3D"this.href=3D'javascript:';return true;=
">ric...@metafoo.co.uk</a>&gt; wrote:</div><br><blockquote type=3D"cite"><d=
iv dir=3D"ltr"><div class=3D"gmail_quote">Or use a C-style cast from T* to =
B*. C-style derived-to-base casts ignore whether the base class is accessib=
le (see [expr.cast]p4).</div></div></blockquote><br></div><div>Ah, thanks! =
I forgot this. Fits perfectly. Certainly needs a code comment, and the lang=
uage would probably benefit from CRTP-specific access specifiers, but the p=
roblem just got smaller.</div><div><br></div><div>(For folks following alon=
g, C casts degenerate to <font face=3D"Courier">reinterpret_cast</font>&nbs=
p;when the target is not in the inheritance hierarchy, so a <font face=3D"C=
ourier">static_assert</font> on&nbsp;<font face=3D"Courier">std::is_base_of=
</font>, which also ignores accessibility, adds significant safety.)</div><=
div><br></div></div></div></blockquote></div><div><br class=3D"webkit-block=
-placeholder"></div>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" 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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br>
</blockquote></div><br></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_25584A7B-7921-4B6D-995D-6FBE1BF4E476--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Wed, 18 Jun 2014 11:12:26 -0700 (PDT)
Raw View
------=_Part_194_25834939.1403115146341
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I don't get it, why don't you just require the derived class to friend its=
=20
base?

#include <iostream>

template <class T> struct B
{
    void f();
};

struct D : private B<D>
{
    friend class B<D>;
   =20
    void g() {std::cout << "D::g" << std::endl;}
    void h() {f();}
};

template<class T> void B<T>::f() {
    static_cast<T*>(this)->g();
}

int main()
{
    D d;
    d.h();
}

Doesn't that bypass access control in exactly the way you wanted?


On Sunday, 15 June 2014 14:33:36 UTC+1, David Krauss wrote:
>
> No, the purpose of the static_assert I mentioned is to prevent=20
> reinterpret_cast from happening.
>
> What we want is an access-bypassed static_cast semantic.
>
>
> On 2014=E2=80=9306=E2=80=9315, at 8:35 PM, inkwizyt...@gmail.com <javascr=
ipt:> wrote:
>
> This wont be UB and only work when this class is first of base classes?
>
> On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:
>>
>>
>> On 2014=E2=80=9306=E2=80=9315, at 6:06 AM, Richard Smith <ric...@metafoo=
..co.uk> wrote:
>>
>> Or use a C-style cast from T* to B*. C-style derived-to-base casts ignor=
e=20
>> whether the base class is accessible (see [expr.cast]p4).
>>
>>
>> Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code=20
>> comment, and the language would probably benefit from CRTP-specific acce=
ss=20
>> specifiers, but the problem just got smaller.
>>
>> (For folks following along, C casts degenerate to reinterpret_cast when=
=20
>> the target is not in the inheritance hierarchy, so a static_assert on=20
>> std::is_base_of, which also ignores accessibility, adds significant=20
>> safety.)
>>
>>
> --=20
>
> ---=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_194_25834939.1403115146341
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I don't get it, why don't you just require the derived cla=
ss to friend its base?<br><br><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">#include</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">&lt;iostream&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">template</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> B<br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struc=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> D </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">private</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> B</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">D</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">friend</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> B</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">D</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&gt;;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; <br>&nbsp; &nbsp; </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> g</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"D::g"</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">endl</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> h</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">();}</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> B</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">static_cast</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">*&gt;(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">th=
is</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)-&gt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">g</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp; D d</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>&nbsp; &nbsp; d</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">h<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br=
>Doesn't that bypass access control in exactly the way you wanted?<br><br><=
br>On Sunday, 15 June 2014 14:33:36 UTC+1, David Krauss  wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div>N=
o, the purpose of the static_assert I mentioned is to prevent reinterpret_c=
ast from happening.</div><div><br></div><div>What we want is an access-bypa=
ssed static_cast semantic.</div><div><br></div><br><div><div>On 2014=E2=80=
=9306=E2=80=9315, at 8:35 PM, <a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"LBKR5uFsZxcJ" onmousedown=3D"this.href=3D'javascript:=
';return true;" onclick=3D"this.href=3D'javascript:';return true;">inkwizyt=
....@gmail.com</a> wrote:</div><br><blockquote type=3D"cite"><div dir=3D"ltr=
">This wont be UB and only work when this class is first of base classes?<b=
r><br>On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><=
br></div><div><div><div>On 2014=E2=80=9306=E2=80=9315, at 6:06 AM, Richard =
Smith &lt;<a>ric...@metafoo.co.uk</a>&gt; wrote:</div><br><blockquote type=
=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_quote">Or use a C-style cast=
 from T* to B*. C-style derived-to-base casts ignore whether the base class=
 is accessible (see [expr.cast]p4).</div></div></blockquote><br></div><div>=
Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code comment, =
and the language would probably benefit from CRTP-specific access specifier=
s, but the problem just got smaller.</div><div><br></div><div>(For folks fo=
llowing along, C casts degenerate to <font face=3D"Courier">reinterpret_cas=
t</font>&nbsp;when the target is not in the inheritance hierarchy, so a <fo=
nt face=3D"Courier">static_assert</font> on&nbsp;<font face=3D"Courier">std=
::is_base_of</font>, which also ignores accessibility, adds significant saf=
ety.)</div><div><br></div></div></div></blockquote></div><div><br></div>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
LBKR5uFsZxcJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.or=
g</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"LBKR5uFsZxcJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">s=
td-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</blockquote></div><br></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_194_25834939.1403115146341--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Wed, 18 Jun 2014 15:26:28 -0400
Raw View
--001a11c1200ea0fc3804fc213cd7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I am trying to wrap my head around the whole CRTP with a private base. If
this is a private base, the implication is that the CRTP class will only be
accessible from the derived type, right? If that is the case, only the
derived type or a friend of it can call on CRTP member functions... This is
not the CRTP I am used to see, but if we follow that, then why not have the
functions be static and have the derived type pass the pointer?

template <typename T>
struct CRTP {
   static void foo(T *t) { t->bar(); }
};
class Derived : CRTP<Derived> {
   void bar();
   void call() {
       foo(this);
   }
};

But I am not sure I completely understand what the use cases for CRTP with
private inheritance are.

    David

P.S. I have used CRTP with private inheritance to provide operators to
types, but in this case there are no casts involved:

template <typename T>
struct relops {
    friend bool operator>(T const &a, T const &b) {
        return b < a;
    }
// ... other operators: <=3D, >=3D ...
};
class MyType : relops<MyType> {
   ...
};
bool operator<(MyType const &a, MyType const &b) { ... }


On Wed, Jun 18, 2014 at 2:12 PM, Diggory Blake <diggsey@googlemail.com>
wrote:

> I don't get it, why don't you just require the derived class to friend it=
s
> base?
>
> #include <iostream>
>
> template <class T> struct B
> {
>
>     void f();
>
> };
>
> struct D : private B<D>
> {
>
>     friend class B<D>;
>
>     void g() {std::cout << "D::g" << std::endl;}
>     void h() {f();}
> };
>
> template<class T> void B<T>::f() {
>     static_cast<T*>(this)->g();
>
> }
>
> int main()
> {
>     D d;
>     d.h();
> }
>
> Doesn't that bypass access control in exactly the way you wanted?
>
>
> On Sunday, 15 June 2014 14:33:36 UTC+1, David Krauss wrote:
>>
>> No, the purpose of the static_assert I mentioned is to prevent
>> reinterpret_cast from happening.
>>
>> What we want is an access-bypassed static_cast semantic.
>>
>>
>> On 2014=E2=80=9306=E2=80=9315, at 8:35 PM, inkwizyt...@gmail.com wrote:
>>
>> This wont be UB and only work when this class is first of base classes?
>>
>> On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:
>>>
>>>
>>> On 2014=E2=80=9306=E2=80=9315, at 6:06 AM, Richard Smith <ric...@metafo=
o.co.uk> wrote:
>>>
>>> Or use a C-style cast from T* to B*. C-style derived-to-base casts
>>> ignore whether the base class is accessible (see [expr.cast]p4).
>>>
>>>
>>> Ah, thanks! I forgot this. Fits perfectly. Certainly needs a code
>>> comment, and the language would probably benefit from CRTP-specific acc=
ess
>>> specifiers, but the problem just got smaller.
>>>
>>> (For folks following along, C casts degenerate to reinterpret_cast when
>>> the target is not in the inheritance hierarchy, so a static_assert on
>>> std::is_base_of, which also ignores accessibility, adds significant
>>> safety.)
>>>
>>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>>
>> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
>> proposals/.
>>
>>
>>  --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--001a11c1200ea0fc3804fc213cd7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I am trying to wrap my head around the whole CRTP with a p=
rivate base. If this is a private base, the implication is that the CRTP cl=
ass will only be accessible from the derived type, right? If that is the ca=
se, only the derived type or a friend of it can call on CRTP member functio=
ns... This is not the CRTP I am used to see, but if we follow that, then wh=
y not have the functions be static and have the derived type pass the point=
er?<br>
<br>template &lt;typename T&gt;<br>struct CRTP {<br>=C2=A0 =C2=A0static voi=
d foo(T *t) { t-&gt;bar(); }<br>};<br>class Derived : CRTP&lt;Derived&gt; {=
<br>=C2=A0 =C2=A0void bar();<br>=C2=A0 =C2=A0void call() {<br>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0foo(this);<br>=C2=A0 =C2=A0}<br>};<br><br>
But I am not sure I completely understand what the use cases for CRTP with =
private inheritance are.<br><br>=C2=A0 =C2=A0 David<br><br>P.S. I have used=
 CRTP with private inheritance to provide operators to types, but in this c=
ase there are no casts involved:<br>
<br>template &lt;typename T&gt;<br>struct relops {<br>=C2=A0 =C2=A0 friend =
bool operator&gt;(T const &amp;a, T const &amp;b) {<br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 return b &lt; a;<br>=C2=A0 =C2=A0 }<br>// ... other operators: &lt;=
=3D, &gt;=3D ...<br>};<br>class MyType : relops&lt;MyType&gt; {<br>
=C2=A0 =C2=A0...<br>};<br>bool operator&lt;(MyType const &amp;a, MyType con=
st &amp;b) { ... }</div><div class=3D"gmail_extra"><br><br><div class=3D"gm=
ail_quote">On Wed, Jun 18, 2014 at 2:12 PM, Diggory Blake <span dir=3D"ltr"=
>&lt;<a href=3D"mailto:diggsey@googlemail.com" target=3D"_blank">diggsey@go=
oglemail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I don&#39;t get it, why don=
&#39;t you just require the derived class to friend its base?<br><br><div s=
tyle=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bor=
der-style:solid;border-width:1px;word-wrap:break-word">
<code><div><div class=3D""><span style=3D"color:#800">#include</span><span =
style=3D"color:#000"> </span><span style=3D"color:#080">&lt;iostream&gt;</s=
pan><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">te=
mplate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">struct</span><span style=3D"color:#000"=
> B<br>
</span><span style=3D"color:#660">{</span></div><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">void</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">();</span><div class=3D=
""><span style=3D"color:#000"><br>
</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><=
br></span><span style=3D"color:#008">struct</span><span style=3D"color:#000=
"> D </span><span style=3D"color:#660">:</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">private</span><span style=3D"color:#000">=
 B</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">D=
</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br=
>
</span><span style=3D"color:#660">{</span></div><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">friend</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> B</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#000">D</span><span style=3D"color:#660">&gt;;</span><span style=
=3D"color:#000"><br>
=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">void</spa=
n><span style=3D"color:#000"> g</span><span style=3D"color:#660">()</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">cout </span><span style=3D"color:#660">&lt;&lt;</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#080">&quot;D::g&quot=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;&=
lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">endl</span><span style=3D"color:#660">;=
}</span><span style=3D"color:#000"><br>
=C2=A0 =C2=A0 </span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> h</span><span style=3D"color:#660">()</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0">f</span><span style=3D"color:#660">();}</span><span style=3D"color:#000"=
><br>
</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><=
br></span><span style=3D"color:#008">template</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:=
#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">void</span><span style=3D"color:#00=
0"> B</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000=
">T</span><span style=3D"color:#660">&gt;::</span><span style=3D"color:#000=
">f</span><span style=3D"color:#660">()</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>
=C2=A0 =C2=A0 </span><span style=3D"color:#008">static_cast</span><span sty=
le=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">*&gt;(</span><span style=3D"color:#008">this</span><span st=
yle=3D"color:#660">)-&gt;</span><span style=3D"color:#000">g</span><span st=
yle=3D"color:#660">();</span><div class=3D"">
<span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><s=
pan style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> main</span><span style=3D"color:#660">()</spa=
n><span style=3D"color:#000"><br>
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 D d</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 d</span><span style=3D"color:#660">.</span><sp=
an style=3D"color:#000">h</span><span style=3D"color:#660">();</span><span =
style=3D"color:#000"><br>
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></=
span></div></div></code></div><br>Doesn&#39;t that bypass access control in=
 exactly the way you wanted?<br><br><br>On Sunday, 15 June 2014 14:33:36 UT=
C+1, David Krauss  wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div>No, the purpose of the static_asse=
rt I mentioned is to prevent reinterpret_cast from happening.</div><div><br=
></div><div>What we want is an access-bypassed static_cast semantic.</div>
<div><br></div><br><div><div class=3D""><div>On 2014=E2=80=9306=E2=80=9315,=
 at 8:35 PM, <a>inkwizyt...@gmail.com</a> wrote:</div><br></div><blockquote=
 type=3D"cite"><div class=3D""><div dir=3D"ltr">This wont be UB and only wo=
rk when this class is first of base classes?<br>
<br>On Sunday, June 15, 2014 5:17:56 AM UTC+2, David Krauss wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><br=
></div>
<div><div><div>On 2014=E2=80=9306=E2=80=9315, at 6:06 AM, Richard Smith &lt=
;<a>ric...@metafoo.co.uk</a>&gt; wrote:</div><br><blockquote type=3D"cite">=
<div dir=3D"ltr"><div class=3D"gmail_quote">Or use a C-style cast from T* t=
o B*. C-style derived-to-base casts ignore whether the base class is access=
ible (see [expr.cast]p4).</div>
</div></blockquote><br></div><div>Ah, thanks! I forgot this. Fits perfectly=
.. Certainly needs a code comment, and the language would probably benefit f=
rom CRTP-specific access specifiers, but the problem just got smaller.</div=
>
<div><br></div><div>(For folks following along, C casts degenerate to <font=
 face=3D"Courier">reinterpret_cast</font>=C2=A0when the target is not in th=
e inheritance hierarchy, so a <font face=3D"Courier">static_assert</font> o=
n=C2=A0<font face=3D"Courier">std::is_base_of</font>, which also ignores ac=
cessibility, adds significant safety.)</div>
<div><br></div></div></div></blockquote></div><div><br></div>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<div class=
=3D""><br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></blockquote></div><br></div></blockquote></div><div class=3D"HOEnZb"=
><div class=3D"h5">

<p></p>

-- <br>
<br>
--- <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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c1200ea0fc3804fc213cd7--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 19 Jun 2014 09:35:59 +0800
Raw View
--Apple-Mail=_CF3BF895-51F3-497B-83B3-C3B85A93B5BD
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-06-19, at 3:26 AM, David Rodr=EDguez Ibeas <dibeas@ieee.org> wrote:

> I am trying to wrap my head around the whole CRTP with a private base. If=
 this is a private base, the implication is that the CRTP class will only b=
e accessible from the derived type, right? If that is the case, only the de=
rived type or a friend of it can call on CRTP member functions... This is n=
ot the CRTP I am used to see, but if we follow that, then why not have the =
functions be static and have the derived type pass the pointer?

My use case involves protected access, not private, but you might have a po=
int. Reviewing my code, adding the C-style cast didn't really buy much. Her=
e is my generic crtp_base class:

template< typename derived >
class crtp_base {
    void check() const
        { static_assert ( std::is_base_of< crtp_base, derived >::value, "No=
n-CRTP use of base." ); }
protected:
    derived & derived_this()
        { check(); return ( derived & ) * this; }
    derived const & derived_this() const
        { check(); return ( derived const & ) * this; }
};

This class only provides derived_this, intended for any CRTP base of derive=
d. As a public interface, derived_this is useless so it's protected. Does t=
he same argument apply to class crtp_base?

crtp_base< derived > =3D=3Daccess?=3D> mixin< derived > =3D=3Dpublic=3D=3D>=
 derived

The C cast allows me to choose protected access for crtp_base. It's cleaner=
 and consistent, but a bit pointless since the entire interface is protecte=
d anyway. In retrospect, I should probably revert it back to public inherit=
ance and static_cast.

Usually, a mixin knows whether it's going to be useful to the public or onl=
y to the inheriting class, and it can define the its own interface such tha=
t public inheritance is correct. Only when the derived class "knows better"=
 should it apply a stronger qualification. Even then, qualifying the inheri=
ted interface with using declarations is almost as clean as qualifying the =
inheritance itself.

I do think the language fails to provide good qualification for the interfa=
ce provided by a derived class to its CRTP base. Why not friendship? ...


On 2014-06-19, at 2:12 AM, Diggory Blake <diggsey@googlemail.com> wrote:

> I don't get it, why don't you just require the derived class to friend it=
s base?
>=20
> Doesn't that bypass access control in exactly the way you wanted?

Since friendship cannot be transitive, a friended class must not delegate i=
ts functionality. friend B<D>; buys you exactly one mixin, but the pattern =
doesn't work for an extended mixin derived from another, or a composite mix=
in derived from two others.

But, this is a different issue from my original post. "Exactly" what I want=
ed in that case was only that the CRTP cast itself would work, without sugg=
esting that a derived-to-base detail interface exists as well.

Probably, the solution to the new issue is explicitly transitive friendship=
, irrespective of inheritance. I'm sure that design space has been explored=
 before. Although my current inheritance hierarchy is leaking a little publ=
ic access due to this very issue, I'm not inclined to attack it right now :=
P .

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_CF3BF895-51F3-497B-83B3-C3B85A93B5BD
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><div><div><br></div><d=
iv><div>On 2014&ndash;06&ndash;19, at 3:26 AM, David Rodr=EDguez Ibeas &lt;=
<a href=3D"mailto:dibeas@ieee.org">dibeas@ieee.org</a>&gt; wrote:</div><br =
class=3D"Apple-interchange-newline"><blockquote type=3D"cite">I am trying t=
o wrap my head around the whole CRTP with a private base. If this is a priv=
ate base, the implication is that the CRTP class will only be accessible fr=
om the derived type, right? If that is the case, only the derived type or a=
 friend of it can call on CRTP member functions... This is not the CRTP I a=
m used to see, but if we follow that, then why not have the functions be st=
atic and have the derived type pass the pointer?<br></blockquote><div><br><=
/div><div>My use case involves protected access, not private, but you might=
 have a point. Reviewing my code, adding the C-style cast didn&rsquo;t real=
ly buy much. Here is my generic&nbsp;<font face=3D"Courier">crtp_base</font=
> class:</div><div><br></div><div><div><font face=3D"Courier">template&lt; =
typename derived &gt;</font></div><div><font face=3D"Courier">class crtp_ba=
se {</font></div><div><font face=3D"Courier">&nbsp; &nbsp; void check() con=
st</font></div><div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &nbsp; { st=
atic_assert ( std::is_base_of&lt; crtp_base, derived &gt;::value, "Non-CRTP=
 use of base." ); }</font></div><div><font face=3D"Courier">protected:</fon=
t></div><div><font face=3D"Courier">&nbsp; &nbsp; derived &amp; derived_thi=
s()</font></div><div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &nbsp; { c=
heck(); return ( derived &amp; ) * this; }</font></div><div><font face=3D"C=
ourier">&nbsp; &nbsp; derived const &amp; derived_this() const</font></div>=
<div><font face=3D"Courier">&nbsp; &nbsp; &nbsp; &nbsp; { check(); return (=
 derived const &amp; ) * this; }</font></div><div><font face=3D"Courier">};=
</font></div><div><br></div></div><div>This class only provides&nbsp;<span =
style=3D"font-family: Courier;">derived_this</span>, intended for any CRTP =
base of <font face=3D"Courier">derived</font>. As a public interface,&nbsp;=
<font face=3D"Courier">derived_this</font> is useless so it&rsquo;s protect=
ed. Does the same argument apply to <font face=3D"Courier">class crtp_base<=
/font>?</div><div><br></div><div><font face=3D"Courier">crtp_base&lt; deriv=
ed &gt; =3D=3Daccess?=3D&gt; mixin&lt; derived &gt; =3D=3Dpublic=3D=3D&gt; =
derived</font></div><div><br></div><div>The C cast allows me to choose <fon=
t face=3D"Courier">protected</font> access for <font face=3D"Courier">crtp_=
base</font>. It&rsquo;s cleaner and consistent, but a bit pointless since t=
he entire interface is <font face=3D"Courier">protected</font> anyway. In r=
etrospect, I should probably revert it back to <font face=3D"Courier">publi=
c</font> inheritance and <font face=3D"Courier">static_cast</font>.</div><d=
iv><br></div><div>Usually, a mixin knows whether it&rsquo;s going to be use=
ful to the public or only to the inheriting class, and it can define the it=
s own interface such that public inheritance is correct. Only when the deri=
ved class &ldquo;knows better&rdquo; should it apply a stronger qualificati=
on. Even then, qualifying the inherited interface with <font face=3D"Courie=
r">using</font> declarations is almost as clean as qualifying the inheritan=
ce itself.</div><div><br></div><div>I do think the language fails to provid=
e good qualification for the interface provided by a derived class to its C=
RTP base. Why not friendship? &hellip;</div><div><br></div><div><br></div><=
div><div>On 2014&ndash;06&ndash;19, at 2:12 AM, Diggory Blake &lt;<a href=
=3D"mailto:diggsey@googlemail.com">diggsey@googlemail.com</a>&gt; wrote:</d=
iv><br class=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div d=
ir=3D"ltr">I don't get it, why don't you just require the derived class to =
friend its base?<br><br>Doesn't that bypass access control in exactly the w=
ay you wanted?<br></div></blockquote><div><br></div>Since friendship cannot=
 be transitive, a friended class must not delegate its functionality.&nbsp;=
<font face=3D"Courier">friend B&lt;D&gt;;</font>&nbsp;buys you exactly one =
mixin, but the pattern doesn&rsquo;t work for an extended mixin derived fro=
m another, or a composite mixin derived from two others.<br><div><br></div>=
</div><div>But, this is a different issue from my original post. &ldquo;Exa=
ctly&rdquo; what I wanted in that case was only that the CRTP cast itself w=
ould work, without suggesting that a derived-to-base detail interface exist=
s as well.</div><div><br></div><div>Probably, the solution to the new issue=
 is explicitly transitive friendship, irrespective of inheritance. I&rsquo;=
m sure that design space has been explored before. Although my current inhe=
ritance hierarchy is leaking a little public access due to this very issue,=
 I&rsquo;m not inclined to attack it right now :P .</div><div><br></div></d=
iv></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_CF3BF895-51F3-497B-83B3-C3B85A93B5BD--

.