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

Base's using a type defined in Derived, in a Curiously Recurring Template Pattern

363 views
Skip to first unread message

Seungbeom Kim

unread,
Jan 10, 2005, 5:14:14 AM1/10/05
to
In the Curiously Recurring Template Pattern below, the base's trying to
use a type defined in the derived gives an error saying it's incomplete.
But I don't see why it's incomplete. Can anyone explain this?
And how can I get around this problem?


template <class Derived>
struct base
{
typedef typename Derived::value_type value_type;
//-------------------^ incomplete type is not allowed
};

template <typename T>
struct derived : public base< derived<T> >
{
typedef T value_type;
};

void foo(derived<int>) { }

--
Seungbeom Kim

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

Maxim Yegorushkin

unread,
Jan 10, 2005, 3:24:08 PM1/10/05
to
Seungbeom Kim wrote:

> In the Curiously Recurring Template Pattern below, the base's trying to
> use a type defined in the derived gives an error saying it's incomplete.
> But I don't see why it's incomplete. Can anyone explain this?
>

> template <class Derived>
> struct base
> {
> typedef typename Derived::value_type value_type;
> //-------------------^ incomplete type is not allowed
> };
>
> template <typename T>
> struct derived : public base< derived<T> >
> {
> typedef T value_type;
> };
>
> void foo(derived<int>) { }

Because at the point of instantiation of base, which is 'struct derived :
public base< derived<T> >' derived is incomplete. It becomes complete only
after {}; following struct.

> And how can I get around this problem?

Postpone the access to Derived's internals. Although there is no way for
base to expose Derived's types via typedef's, it actually may use
Derived's types and functions inside base's function definitions, since
template's class functions gets instantiated only when they are used.

template <class Derived>
struct base
{

void foo()


{
typedef typename Derived::value_type value_type;
}

};

--
Maxim Yegorushkin

Seungbeom Kim

unread,
Jan 11, 2005, 5:43:56 AM1/11/05
to
Maxim Yegorushkin wrote:
>
> Postpone the access to Derived's internals. Although there is no way for
> base to expose Derived's types via typedef's, it actually may use
> Derived's types and functions inside base's function definitions, since
> template's class functions gets instantiated only when they are used.
>
> template <class Derived>
> struct base
> {
> void foo()
> {
> typedef typename Derived::value_type value_type;
> }
> };

Thank you. However, unfortunately, the type should be used in the
signature of a base's function, so the trick above cannot work.

I think the type for the typedef should be supplied through a template
parameter of base and the typedef moved into the definition of base.

--
Seungbeom Kim

gle...@pixelglow.com

unread,
Jan 11, 2005, 3:53:23 PM1/11/05
to
Consider the point at which base <derived <T> > is declared. There it
can only see derived as a forward declared class, not the actual
complete type. The solution is to pass in the type(s) you want to use
within:

template <class Derived, class ValueType>
struct base
{
typedef ValueType value_type; // ok now
};

template <typename T>
struct derived : public base< derived<T>, T>
{
typedef T value_type;

};

If the redundancy bothers you can use a template template parameter and
lose a little flexibility:

template <template <typename> class Derived, class ValueType>
struct base
{
typedef ValueType value_type; // ok now
};

template <typename T>
struct derived : public base< derived, T>
{
typedef T value_type;
};

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com

Tom Widmer

unread,
Jan 11, 2005, 5:42:10 PM1/11/05
to

Seungbeom Kim wrote:
> In the Curiously Recurring Template Pattern below, the base's trying
to
> use a type defined in the derived gives an error saying it's
incomplete.
> But I don't see why it's incomplete. Can anyone explain this?

In the base class clause of a class, that class is incomplete.

> And how can I get around this problem?

Remove the typedef or add a second template parameter, T, to base.

Tom

Nicola....@objectway.it

unread,
Jan 11, 2005, 6:45:40 PM1/11/05
to
In alternative to Maxim's suggestion you could move the derived class's
typedefs to a traits class template, specialized on the derived class.
Then a declaration of the derived class would be sufficient to compile
your code.

Cheers,
Nicola Musatti

0 new messages