CRTP question

M

michael.alexeev

Hi all,

Consider the following program:

template <class T>
struct Traits{
typedef typename T::type_t type_t; //line 3
};

template <class Derived>
struct Base{
typedef typename Traits<Derived>::type_t type_t; // line 8
type_t foo() {
Derived& self = static_cast<Derived&>(*this);
return self.bar();
}

};

template<typename T>
struct Derived : public Base<Derived<T> >{
typedef T type_t;
type_t bar() {
return type_t();
}
};

int main(){
Derived<int> d;
return 0;
}

Compiler (gcc 4.0.2) complains with the following message:

t.cxx: In instantiation of Traits<Derived<int> >:
t.cxx:8: instantiated from Base<Derived<int> >
t.cxx:17: instantiated from Derived<int>
t.cxx:25: instantiated from here
t.cxx:3: error: no type named type_t in struct Derived<int>

I was under the impresion that declarations in the Base class template
are instantiated when the Derived class is declared which means that
Derived::type_t is accessable. Looks like it's not a case.

Any help/walkaround is greatly appreciated.

Mike
 
V

Victor Bazarov

Consider the following program:

template <class T>
struct Traits{
typedef typename T::type_t type_t; //line 3
};

template <class Derived>
struct Base{
typedef typename Traits<Derived>::type_t type_t; // line 8
type_t foo() {
Derived& self = static_cast<Derived&>(*this);
return self.bar();
}

};

template<typename T>
struct Derived : public Base<Derived<T> >{
typedef T type_t;
type_t bar() {
return type_t();
}
};

int main(){
Derived<int> d;
return 0;
}

Compiler (gcc 4.0.2) complains with the following message:

t.cxx: In instantiation of Traits<Derived<int> >:
t.cxx:8: instantiated from Base<Derived<int> >
t.cxx:17: instantiated from Derived<int>
t.cxx:25: instantiated from here
t.cxx:3: error: no type named type_t in struct Derived<int>

I was under the impresion that declarations in the Base class template
are instantiated when the Derived class is declared which means that
Derived::type_t is accessable. Looks like it's not a case.

The problem is that by the time it gets to use 'Derived<int>::type_t',
during instantiating of Derived<int>::Base<Derived<int> >, the inner
Any help/walkaround is greatly appreciated.

You could try specialising 'Traits' this way:

template<class T> class Derived; // forward-delcaration
template<class T> class Traits<Derived<T> > { typedef T type_t; };

....since you know that 'type_t' is going to be the same as T. And then
declare your Base, and so forth.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top