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! ]
> 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
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
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
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
Cheers,
Nicola Musatti