What about my vector implementation?

Started by
19 comments, last by cignox1 16 years, 6 months ago
Yeah, I like to have * just do element-wise multiplication too, and have named functions for dot and cross multiplication (because everyone seems to have a differing opinion on which operators to use). Only use operator overloading if it's going to be obvious what the operator does - If I saw vec1 = vec2|vec3, I would assume it was some kind of element-wise logical-or...

Quote:Original post by JohnBolton
Quote:Original post by SiCrane
For dot and cross products I tend to do something like:
*** Source Snippet Removed ***
So then I can use "A <dot> B" or "A <cross> B" to calculate the dot or cross product. On the down side, it's not idiomatic C++, so it tends to generate WTF comments from people seeing it used before seeing how its implemented.

That is one of the most ridiculous things I have ever seen.

Ridiculous? Yes.
Confusing? Yes.
Smothered in awesome sauce? YES!!
Advertisement
I see many responses... cool :-)
But I must say I'm a bit surprised about the fact that almost all the replies are about the use of operator overloading for dot and cross products. This is a topic covered in many places and I'm aware of the fact that operators overloading can lead to confusing practices and should be used only where overloaded operators have a behaviour semantically similar to the original operators (that's why my previous class also had named methods to perform dot and cross products: I just did't add them to the new version yet).

However, I'm more interested in your advices about the class as a whole, i.e how I used templates. const correctness, mathematical operations, interface design and so on (I suppose that nothing really wrong was made, otherwise you would have pointed it out :-)...
Com'on guys, Do you have some more observations not about those operators? ;-)

QUESTION:
When you need to add a scalar value (i.e. 0 or 1) which form do you use?
-T(0)
-(T)0
-T(0.0)
-(T)0.0

And are there reasons to choose one over the others?

This doesn't mean I'm not grateful for your replies, of course!

Thank you again!
Alessandro
You need a typedef T element_type; in your class to make generic programmer easier (so that you can deduce what T is in a template function where the vector is a parameter).
cignox1, you may consider using expression templates so that code like:
Vector4<float> v5 = v1 + v2 + v3 + v4;

doesn't produce unneccesssary temporary objects.
Quote:You need a typedef T element_type; in your class to make generic programmer easier (so that you can deduce what T is in a template function where the vector is a parameter).


Quote:
cignox1, you may consider using expression templates so that code like:
Vector4<float> v5 = v1 + v2 + v3 + v4;

doesn't produce unneccesssary temporary objects.


Could you both explain to me what you mean? I'm not sure to fully understand...

EDIT: perhaps I understood what ToohrVyk meant: I start to implement the ray class. I will parametrize it with the vector type (vector4 or vector2 will be accepted):
template<typename T>
class ray
{
public:
T origin, direction;
};

If I put the typedef inside the vector class I can then do something like this:
T.element_type a = ...
where I need temp values for calculations, with the correct type without requiring to ask for a second type parameter when instantiating the template. Did I get it?

[Edited by - cignox1 on October 12, 2007 7:55:20 AM]
Quote:Original post by cignox1
Quote:You need a typedef T element_type; in your class to make generic programmer easier (so that you can deduce what T is in a template function where the vector is a parameter).


Quote:
cignox1, you may consider using expression templates so that code like:
Vector4<float> v5 = v1 + v2 + v3 + v4;

doesn't produce unneccesssary temporary objects.


Could you both explain to me what you mean? I'm not sure to fully understand...


T is a typename, but this does notimply that this is a type of vector elements.
Making a typedef element_type will make it clear that it is.

Expression templates are a great way to speed up your code. You can read about it here or just google gamedev for it.
Quote:Original post by JohnBolton
That is one of the most ridiculous things I have ever seen. It deserves to be submitted to The Daily WTF. I am really surprised that someone of your caliber would write that. Oh well, I guess everyone has their vices. It should be obvious that I am not a fan of Boost.Spirit.


If it's any consolation, the header that implements that in my code library is named "evil.h". It's not really Daily WTF worthy though, since I've never used it in anything but personal projects.
ToohrVyk meant that in the public section of your vector class, add

template<typename T> class vector4{public:    typedef T element_type;    // add this    ...};


This means you can deduce the element type from a vector passed as a parameter to a function template, as in

template <typename T>void DoSomethingWithVector(const T& vec){    T::element_type val = vec.Foo();    ...}


You can implement generic algorithms in this way that aren't dependent on the type vector4 was instantiated with.
Quote:Original post by d00fus
ToohrVyk meant that in the public section of your vector class, add

*** Source Snippet Removed ***

This means you can deduce the element type from a vector passed as a parameter to a function template, as in

*** Source Snippet Removed ***

You can implement generic algorithms in this way that aren't dependent on the type vector4 was instantiated with.



Yep, I realized that just after asking for explanation :-) In fact I added a few words in my previous post to get confirm to my supposition. Incidentally, you reminded me one more time that access to static field in c++ is NOT the same as in c# or Java ;-)

This is a good idea, one of those things that make me wonder if C++ has an actually finite amount of features. After years of programming, one still sees new things. SiCrane post is another one, though I suppose that templates add a new whole set of features...
(I'm not sure if you already know about this, so ignore me if I sound patronizing)

Before you bash on to implementing your vector4 for use in a raytracer, I'd like to note that having an SSE-enabled vector4 structure is not that useful. To get most out of SIMD, you'll probably want to have a SSE-enabled structure that stores 4 3D vectors (12 elements) in a SoA (structure of arrays) manner. For example, see Using Intel Streaming SIMD Extensions for 3D Geometry Processing.

This topic is closed to new replies.

Advertisement