Reputation: 29966
This is partly related to this SO question.
I have two classes, both of them are templated, e.g.:
class Base
{
public:
template< class T > void operator=(T other)
{
//irrelevant
}
Derived toDerived()
{
Derived d;
//do stuff;
return d;
}
};
class Derived: public Base
{
public:
template< class T > void foo( T other )
{
//do stuff
}
};
As you can see, both are templated, and inside of the Base
class function I need to create an instance of Derived
. Of course, the way it is now I'm getting an error Derived does not name a type
. Unfortunately though, I can't just forward-declare Derived
, because it will lead to another error variable 'Derived d ' has initializer but incomplete type
.
From the SO question I mentioned above I understand that the compiler needs to know about all the template parameters to be able to forward-declare it correctly. But obviousle I can't just move Derived
declaration up, because it will lead to exactly same problem, just vice-versa.
Is there a way to accomplish this?
Upvotes: 1
Views: 728
Reputation: 145349
You can do
class Derived;
class Base
{
public:
template< class T > void operator=(T other)
{
//irrelevant
}
Derived toDerived();
};
class Derived: public Base
{
public:
template< class T > void foo( T other )
{
//do stuff
}
};
Derived Base::toDerived()
{
Derived d;
//do stuff;
return d;
}
As you can see it has nothing to do with templates.
Also, this design simply doesn't feel right.
Upvotes: 3
Reputation: 9089
This problem has nothing with templates. You could just use forward declaration of Derived
to compile declaration of Base::toDerived()
and move the function definition
depending on Derived
after Derived
definition:
// Forward declaration of Derived
class Derived;
// Definition of Base
class Base
{
public:
// Base::toDerived() declaration only
Derived toDerived();
};
// Definition of Derived
class Derived: public Base
{
public:
...
};
// Base::toDerived() definition
inline Derived Base::toDerived()
{
Derived d;
// Do dirty things
return d;
}
Upvotes: 4
Reputation: 35449
// Declare, but do not define
class Derived;
class Base {
public:
// Declare, but do not define
// at this point Derived must be declared to be able
// to use it in the return type
Derived toDerived();
};
// Define
class Derived: public Base {
// Rest of definition
};
// At this point Derived is defined
// Define
Derived Base::toDerived()
{
// Implementation goes here
}
Upvotes: 3