Reputation: 847
I've recreated the problem I'm having in the code below:
template<typename T>
class A{
using type = T::type;
type someFunction(/*some parameters*/){/*code for the function*/}
//other stuff
};
template<typename T>
class B : public A<B<T>>{
typedef T type;
//other stuff
};
The problem is that I need to have A have a function with a return type of T::type
, but because B isn't completely declared at the time when A is compiled, I get the error invalid use of incomplete type ‘class B<int>’
when I try to compile it (where int could be replaced with any other type). Is there any way to get this to work?
Upvotes: 2
Views: 97
Reputation: 206737
Is there any way to get this to work?
You can use a traits class to derive the type instead of using:
using type = T::type;
Example:
// Declare TypeSelector
template <typename T> struct TypeSelector;
template <typename T>
class A
{
using type = typename TypeSelector<T>::type;
type someFunction(/*some parameters*/){ return type {}; }
};
// Declare B.
template <typename T> class B;
// Define TypeSelector for <B<T>> first before defining B<T>
template <typename T> struct TypeSelector<B<T>>
{
using type = T;
};
template<typename T>
class B : public A<B<T>>{
using type = typename TypeSelector<T>::type;
//other stuff
};
int main()
{
// Compiles fine.
B<int> a;
}
Upvotes: 1
Reputation: 7601
You can achieve it if you move the definition of B<T>::type
to an external traits-class:
template <typename T>
struct Traits { /* maybe some default values */ };
template<typename T>
class A{
using type = typename Traits<T>::type;
type someFunction(/*some parameters*/){/*code for the function*/}
//other stuff
};
template<typename T>
class B : public A<B<T>>{
using type = typename Traits<B<T>>::type;
};
template <typename T>
struct Traits<B<T>> {
using type = T;
};
Upvotes: 3