Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Extending a template class

I've got the following:

template<typename T> class CVector3
{
    CVector3<T> &normalize();
    // more stuff
};

typedef CVector3<float> Vector3f;
typedef CVector3<double> Vector3d;

I basically want to add a method, toPoint(), that returns a struct Point3f if T=float and a struct Point3d if T=double. I tried replacing the two typedefs with:

class Vector3f: public CVector3<float>
{
    Point3f toPoint() const;
};

class Vector3d: public CVector3<double>
{
    Point3d toPoint() const;
};

This does not work, however, because now normalize() is broken: It no longer returns a Vector3f, but a CVector3<float>, which is incompatible with Vector3f, because it's, in fact, the base class. I could add wrapper methods for normalize() and any other public method in the base class, but I don't want to do this, because it would make maintaining these classes tedious.

I also tried putting the typedefs back in and adding outside the template definition:

template<>
Point3f CVector3<float>::toPoint() const;

template<>
Point3d CVector3<double>::toPoint() const;

This doesn't compile, because toPoint() is not declared inside the template definition. I can't put it inside, because of the return type Point3f/Point3d.

How do I do this? Any help is greatly appreciated!

like image 489
digory doo Avatar asked Aug 13 '26 18:08

digory doo


1 Answers

You could use a traits style helper class.

template<typename T> CVectorTraits {};
template<> CVectorTraits<double> { typedef Point3d PointType; }
template<> CVectorTraits<float> { typedef Point3f PointType; }

template<typename T> class CVector3
{
    CVector3<T> &normalize();
    // more stuff
    typename CVectorTraits<T>::PointType toPoint() const;
};
like image 143
Michael Anderson Avatar answered Aug 15 '26 07:08

Michael Anderson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!