Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Template static inheritance problem

2 views
Skip to first unread message

fgungor

unread,
Dec 22, 2009, 12:16:44 AM12/22/09
to
Hi I am having problems with the following code

class IRenderer
{
public:
virtual int Init() = 0;
virtual int Shutdown() = 0;
};

template <typename TConcreteDevice>
class Device
{
typename TConcreteDevice::TDevice *m_pDevicePtr;

public:

operator typename TConcreteDevice::TDevice *()
{
return m_pDevicePtr;
}
};

class RendererDevice : Device<RendererDevice>
{
public:
typedef IRenderer TDevice;
};

So basically I want to have several types of Devices and every Device
should expose the type of the underlying object it uses.

What is wrong with this code ? It tells me that RendererDevice has no
member named TDevice !?

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

Chris Uzdavinis

unread,
Dec 22, 2009, 6:14:49 PM12/22/09
to
On Dec 21, 11:16 pm, fgungor <neurore...@gmail.com> wrote:
> Hi I am having problems with the following code
...

> template <typename TConcreteDevice>
> class Device
> {
> typename TConcreteDevice::TDevice *m_pDevicePtr;
> };
>
> class RendererDevice : Device<RendererDevice>
> {
> public:
> typedef IRenderer TDevice;
>
> };
>
> So basically I want to have several types of Devices and every Device
> should expose the type of the underlying object it uses.
>
> What is wrong with this code ? It tells me that RendererDevice has no
> member named TDevice !?

At the point of declaring the base class for RendererDevice, the type
of
RendererDevice is still considered an incomplete type. Thus, when
Device<RendererDevice> attempts to extract a nested type, it cannot.

Chris

Yechezkel Mett

unread,
Dec 22, 2009, 6:14:29 PM12/22/09
to
On Dec 22, 7:16 am, fgungor <neurore...@gmail.com> wrote:
> Hi I am having problems with the following code
>
> class IRenderer
> {
> public:
> virtual int Init() = 0;
> virtual int Shutdown() = 0;
>
> };
>
> template <typename TConcreteDevice>
> class Device
> {
> typename TConcreteDevice::TDevice *m_pDevicePtr;
>
> public:
>
> operator typename TConcreteDevice::TDevice *()
> {
> return m_pDevicePtr;
> }
>
> };
>
> class RendererDevice : Device<RendererDevice>
> {
> public:
> typedef IRenderer TDevice;
>
> };
>
> So basically I want to have several types of Devices and every Device
> should expose the type of the underlying object it uses.
>
> What is wrong with this code ? It tells me that RendererDevice has no
> member named TDevice !?

1. The line
> typename TConcreteDevice::TDevice *m_pDevicePtr;
has to be understood when Device<> is instantiated.
2. Device<RendererDevice> is instantiated in the line
> class RendererDevice : Device<RendererDevice>
3. In the above line RendererDevice is not yet complete, and you
cannot access any of its members.

A better compiler error message would have said explicitly that the
class is not complete.

Solutions:

1. Hold m_pDevicePtr by pointer-to-void. static_cast it to
TConcreteDevice::TDevice* in a member function. (Bodies of member
functions are instantiated later, even if they are written in the
class definition.) It's not very pleasant to have void* lying around,
but it is safe -- it's private and you can be sure to initialise and
access it correctly.

2. Move
> typedef IRenderer TDevice;
into a traits class.

3. Pass IRenderer explicitly as a parameter to Device<>.

Yechezkel Mett

0 new messages