Archived

This topic is now archived and is closed to further replies.

Krylloan

Vector (physics style) template, and type conversion.

Recommended Posts

I wish to create a template for 2d, 3d and 4d vectors
  
template <typename I> 
struct v2 {
    union {
        I v[2];
        struct {
            I x, y;
        };
    };
};

Example:
typedef __int32 i32;
typedef __int64 i64;
typedef v2<i32> v2i32;
typedef v2<i64> v2i64;
  
I would like to be able to use conversions like: 1) v2i32 a = v2i32(37, 14); // Create from base units. 2) v2i64 b = v2i64(a); // Create from another v2 vector. I know 1) is easy, and 2 is probably quite hard. Can anyone help here? Thanks for all assistance. [edited by - Krylloan on October 21, 2002 12:17:04 AM]

Share this post


Link to post
Share on other sites
1) you need to use source tags to make sure the HTML doesn't eat up your template parameters.
and 2)


  
template <typename I>
struct v2 {
union {
I v[2];
struct {
I x, y;
};
};
v2(I x_,I y_) : x(x_), y(y_) {}
template <typename OtherType>
v2(v2<OtherType>& other): x(other.x), y(other.y) {
STATIC_CHECK(sizeof(I) >= sizeof(OtherType));
}
};


Not compiled, so there could be bugs.
Uses Loki STATIC_CHECK.

[edited by - risingdragon3 on October 21, 2002 10:21:12 PM]

Share this post


Link to post
Share on other sites
Um, another problem.

I am using the vectors just like I use integers, returning them from functions, assigning one equal to another, etc.

After using your code, I get errors:

no default constructor available.
no copy constructor available.

But I don''t want to construct at all.

This is what I want to do. (Example)

  
v2f64 polar_to_rect(f64 ang, f64 len) {
v3f64 a;
a.x = len * cos(ang);
a.y = len * sin(ang);
return a;
}

v2f64 v = polar_to_rect(2.5, 15);
v2i64 int_v = v2i64(v);


... no memory allocated or deallocated anywhere.
Am I on the right track?

Share this post


Link to post
Share on other sites
Since you have defined a constructor, the default constructor & default copy constructor are voided (as in not automatically included.) Just write an empty constructor that takes no values, and then write a copy constructor.

http://roninmagus.hopto.org
acronymfinder.com - Find any acronym you need!

[edited by - Ronin Magus on October 22, 2002 1:00:22 AM]

Share this post


Link to post
Share on other sites
oops
oh yeah! ...silly me...
well I didn't compile it *feels self-defensive*..
but anyway, yeah, once you do that it should work
about that assurance:
otherwise you may get strange errors when things like this compile:

v2_int E(-10,-10);
v2_char Wierd = E; //will compile and run


clarification:
basically, you can assign 'bigger' (range-wise) numbers to smaller ones, which can lead to problems. I guess, you can restrict the copy constructor and copy operator (which you write in the same way as the copy constructor btw) to just the same types. but, I'm guessing that's not what you want.
just pointing out possible bugy-ness..


[edited by - risingdragon3 on October 22, 2002 1:45:00 AM]

Share this post


Link to post
Share on other sites
I had just completed this post when I realised my error (a missing &). However, the way it screws up is quite interesting.

(So don''t reply to this comment with help)

--- Post about to be sent --------------------------------------

Unfortunately, I''m still breaking previous code.

Below is a fully self-contained example. (replace __i32 and __i64 if your compiler doesn''t support these).


  typedef __int32 i32;
typedef __int64 i64;

template <typename I>
struct v2 {

I x, y;

// Default constructor

inline v2() {}
// Copy constructor (correct?)

inline v2(const v2 &n) {}

// Constructor from base unit

inline v2(I nx, I ny) : x(nx), y(ny) {}

// Constructor from a 2d vector with a different base unit

template <typename O>
inline v2(v2<O> n) : x(n.x), y(n.y) {}
};

typedef v2<i32> v2i32;
typedef v2<i64> v2i64;

inline v2i32 mirror(v2i32 a) {
i32 t = a.x;
a.x = a.y;
a.y = t;
return a;
}

inline v2i64 mirror2(v2i64 a) {
i64 t = a.x;
a.x = a.y;
a.y = t;
return a;
}

int main(int argc, char **argv) {
v2i32 x = v2i32(5, 6);
v2i32 y = v2i32(7, 8);
v2i32 z = x + y;
v2i32 w = z * 17;
v2i32 d = mirror(z);
v2i64 b = v2i64(d);

return 0;
}


somehow, mirror generates no errors, but mirror2 does.
The error I get is "mirror2: local function definitions are illegal."

Yet mirror seems to be a fairly standard function with a matching pair of braces.

The error goes away if I comment out the final constructor from v2, the template

ps, I don''t use v2 anymore, i use kv2. Seems OpenGL uses v2 in it''s headers.

Share this post


Link to post
Share on other sites