From: pfultz2 on
When i use the curiously recurring template pattern, do i need to use
the reinterpret_cast to get the derived class or do i use the
static_cast? And is there a performance penalty in doing this cast?
For example
template<class Derived>
class Base
{
public:
void foo()
{
reinterpret_cast<Derived*>(this)->bar(); //or can i use a static
cast here?
}
};

class MyClass : Base<MyClass>
{
public:
void bar();
};
Im under the assumption that a static cast wouldnt work since the
derived class is not known at compile time. And if it werent then
would a reinterpret_cast be safe, if it were always used this way??

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
pfultz2 wrote:
> When i use the curiously recurring template pattern, do i need to use
> the reinterpret_cast to get the derived class or do i use the
> static_cast?

static_cast. reinterpret_cast will typically only change the type associated
with an address (its actual workings are implementation defined).
static_cast will simply assume that the address is the result of a
conversion from the target type and adjust both the type and, in the case
of e.g. multiple inheritance, the address.

> And is there a performance penalty in doing this cast?
> For example
> template<class Derived>
> class Base
> {
> public:
> void foo()
> {
> reinterpret_cast<Derived*>(this)->bar();
> //or can i use a static cast here?
> }
> };

You _must_ use static_cast here.

> class MyClass : Base<MyClass>
> {
> public:
> void bar();
> };

Try this:

struct test: std::string, Base<test>
{
test()
{
std::cout << this << std::endl;
}
void bar()
{
std::cout << this << std::endl;
}
};

Try this and compare the addresses, using both types of cast.

> Im under the assumption that a static cast wouldnt work since the
> derived class is not known at compile time.

It is not known when Base is first parsed, but it must be known when it is
instantiated, otherwise the call to bar() would be impossible. There is a
distinction between those two phases for templates!

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: restor on
On 12 Jan, 05:33, pfultz2 <pful...(a)yahoo.com> wrote:
> When i use the curiously recurring template pattern, do i need to use
> the reinterpret_cast to get the derived class or do i use the
> static_cast? And is there a performance penalty in doing this cast?
> For example
> template<class Derived>
> class Base
> {
> public:
> void foo()
> {
> reinterpret_cast<Derived*>(this)->bar(); //or can i use a static
> cast here?
>
> }
> };
>
> class MyClass : Base<MyClass>
> {
> public:
> void bar();};
>
> Im under the assumption that a static cast wouldnt work since the
> derived class is not known at compile time. And if it werent then
> would a reinterpret_cast be safe, if it were always used this way??

As far as I know C++, unless you really instantiate a member function
from a template, it is not fully checked. Only the syntax is checked
for obvious (context-independent errors). The names (like Derived) are
looked up only when the function is really used, and by that time the
compiler knows exacltly the relationship between Base and Derived.

Regards,
&rzej


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Jan 12, 5:33 am, pfultz2 <pful...(a)yahoo.com> wrote:
> When i use the curiously recurring template pattern, do i need to use
> the reinterpret_cast to get the derived class or do i use the
> static_cast? And is there a performance penalty in doing this cast?
> For example
> template<class Derived>
> class Base
> {
> public:
> void foo()
> {
> reinterpret_cast<Derived*>(this)->bar(); //or can i use a static
> cast here?
>
> }
> };
>
> class MyClass : Base<MyClass>
> {
> public:
> void bar();};
>
> Im under the assumption that a static cast wouldnt work since the
> derived class is not known at compile time. And if it werent then
> would a reinterpret_cast be safe, if it were always used this way??

static_cast would work, I guess because derived class is known at
template instantiation time ( which is at compile time ;-) ).

reinterpret_cast is a bad idea in this case. I'd say, as a general
rule, reinterpret_cast is never to be used when working with
inheritance (or at least, I can't think of a reason).

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Kenneth 'Bessarion' Boyd on
On Jan 11, 10:33 pm, pfultz2 <pful...(a)yahoo.com> wrote:
> When i use the curiously recurring template pattern, do i need to use
> the reinterpret_cast to get the derived class or do i use the
> static_cast? And is there a performance penalty in doing this cast?
> For example
> template<class Derived>
> class Base
> {
> public:
> void foo()
> {
> reinterpret_cast<Derived*>(this)->bar(); //or can i use a static
> cast here?

I always use static_cast<Derived*>(this) for the CRTP.

static_cast<Derived*>(this)->bar();

> }
> };
>
> class MyClass : Base<MyClass>
> {
> public:
> void bar();};
>
> Im under the assumption that a static cast wouldnt work since the
> derived class is not known at compile time.

The derived class *is* known at compile time. Specifically, it's
known when the template Base<MyClass> is instantiated, and that's good
enough.

> And if it werent then
> would a reinterpret_cast be safe, if it were always used this way??

Actually, a C-style cast [expr.cast] would be safer to misuse here:
its definition would hit the static_cast options second or third, and
would never reach the reinterpret_cast.

I see no explicit guarantees that accessing derived class members
through a reinterpret_cast would be cross-platform safe in C++98 or C+
+0X n3000. Some inferences might be possible from the required memory
model, in the single-inheritance case, when both base and derived
classes are suitable for use as union members. (POD/standard layout
without virtual functions, non-trivial copy/assignment
operators, ....)

I would expect a reinterpret_cast to automatically generate bad code
if the static_cast was adjusting virtual function tables, or
alternately the derived class used multiple inheritance with the CRTP
class not being the first class derived from.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]