Templates and specializations

Started by
13 comments, last by Storyyeller 12 years, 11 months ago

sorry, i meant your class Vector (it was easyer to not hold shift :D)


Hehe ok, making my point clear is proving to be harder than anything else :P


No, Vector is the final class, and it's the one getting all the specializations. I added VectorBase just so that common functions never needing a specialization get grouped, and Vector can inherit those. However, I don't want clients of Vector class to do anything like:



VectorBase<float, 3>* vectors = new Vector<float, 3>[10];



hence the private inheritance. However, this beats the purpose of my obscure inheritance model in a way, as inherited methods get hidden and I need to wrap all of them to make them public again. And if I do public inheritance I would allow code like above, which I don't want.
[ King_DuckZ out-- ]
Advertisement

I already considered making free functions, but I really liked to have everything in my classes.

This is contrary to what's generally recommended, I believe. (Here is an article on the topic you might want to read.)
Why is the possibility of accessing the base class harmful? I can't think of any way it could cause problems, and I think it's very unlikely that you can find a way to share the functions without an accessible base class.

Here's my attempt. The base class is accessible, but I don't really see any problem with this.
Also, this has the advantage of not requiring any type casting.


typedef unsigned long vec_size_t;

template <typename T, vec_size_t S>
class VectorBase
{
T e[S];

public:
vec_size_t size() const {return S;}
T& operator[](vec_size_t i) {return e;}
const T& operator[](vec_size_t i) const {return e;}
};

template <typename T, vec_size_t S>
class Vector: public VectorBase<T, S> {};

//Specializations with conveinence acessors
template <typename T>
class Vector<T,4>: public VectorBase<T, 4>
{
public:
T GetX() const {return this->operator[](0);}
T GetY() const {return this->operator[](1);}
T GetZ() const {return this->operator[](2);}
T GetW() const {return this->operator[](3);}
};

template <typename T>
class Vector<T,3>: public VectorBase<T, 3>
{
public:
T GetX() const {return this->operator[](0);}
T GetY() const {return this->operator[](1);}
T GetZ() const {return this->operator[](2);}
};

template <typename T>
class Vector<T,2>: public VectorBase<T, 2>
{
public:
T GetX() const {return this->operator[](0);}
T GetY() const {return this->operator[](1);}
};

//Operators and free functions
template <typename T, vec_size_t S>
Vector<T, S>& operator += (Vector<T, S>& left, const Vector<T, S>& right)
{
for(vec_size_t i=0; i<S; ++i) {left += right;}
return left;
}

// etc



P.S., How can your cross function be common? Cross products aren't even defined except in 3 and 7 dimensions.
I trust exceptions about as far as I can throw them.

[quote name='King_DuckZ' timestamp='1306365312' post='4815827']
I already considered making free functions, but I really liked to have everything in my classes.

This is contrary to what's generally recommended, I believe. (Here is an article on the topic you might want to read.)
[/quote]

Very interesting reading, I'll be certainly be coding differently after understanding it. Thanks a lot!





Why is the possibility of accessing the base class harmful? I can't think of any way it could cause problems, and I think it's very unlikely that you can find a way to share the functions without an accessible base class.

Here's my attempt. The base class is accessible, but I don't really see any problem with this.
Also, this has the advantage of not requiring any type casting.

P.S., How can your cross function be common? Cross products aren't even defined except in 3 and 7 dimensions.


I wanted my vector classes to have .x, .y and so on, and not .x(), .y() etc, so each specialization declares its own properties (I know I wrote getters in my post, it was just that I felt it was not important to show my point). I can still put the operator[] in the base class after the due refactoring, but at this point I will decide after reading jyk's link. And yes, probably making public inheritance is acceptable.


About the cross product yeah, my bad... that's what I get for posting at 2am :/ Although it can be handy to have a cross on 2D vectors that are zero-extended to 3D, but it's not really what I meant to do... nor to develop some 7D game :D

Well, thanks everyone for the hints!

[ King_DuckZ out-- ]
C++ doesn't have properties, so if you want values to be accessible without a function call, you'll probably have to use some sort of complicated union trickery.
I trust exceptions about as far as I can throw them.

This topic is closed to new replies.

Advertisement