Archived

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

Krylloan

Operators on Template Classes

Recommended Posts

Krylloan    142
I now have the 2d, 3d and 4d struct templates. (see my earlier post - "Vector (physics style) template, and type conversion.") I now want to provide basic operators for them. (+, -, *, /... etc.) Do I define the operator somehow inside the struct definition, or define it external to the struct. If I define them externally, how do I make sure the 2d + operator gets used for 2d vectors while the 3d operator gets used for 3d vectors? Can I use kv2 as some sort of supertype? If I define them internally, what is the correct syntax?
  template <typename I>
struct kv2 { 
    union { 
        I v[2]; struct {
            I x, y;
        };
    };
    
    inline kv2() {}
    inline kv2(const kv2 &n) {}
    inline kv2(I nx, I ny) : x(nx), y(ny) {}

    template <typename O>
    inline kv2(kv2<O> &n) : x(n.x), y(n.y) {}
};  
My current (incorrect) solution is:
  template <class A>
inline A operator + (A a, A b) {
    a.x += b.x;
    a.y += b.y;
    return a;
}

template <class A, typename I>
inline A operator * (A a, I n) {
    a.x *= n;
    a.y *= n;
    return a;
}  
The problem is that a 3d vector (or any other class for that matter) might decide to use the 2d template. What is the correct way to do this? Thanks again for any assistance. Simon Hill

Share this post


Link to post
Share on other sites
Oluseyi    2103
quote:
The problem is that a 3d vector (or any other class for that matter) might decide to use the 2d template.

Why? Addition of a 2d vector to a 3d vector is undefined: the 2d vector must first be promoted to a 3d vector and then the addition may be performed.

Implement the operators as you would for any other templated class.

Share this post


Link to post
Share on other sites
Krylloan    142
To Oluseyi: I meant the addition of two 3d vectors might use the 2d vector addition, not a 2d and a 3d.


Say my file ("kvector.h") looks like this.
----------------------------
// Same as above post
2d Template Definition (kv2)
2d Operators

3d Template Definition (kv3)
3d Operators

4d Template Definition (kv4)
4d Operators
----------------------------

The code for the 2d addition (see above post) would have no trouble attaching itself to the 3d vector template, because the template argument for the 2d addition operator is "class A", not "kv2 a".

Example:


  main() {
v3i32 a = v3i32( 1, 2, 3);
v3i32 b = v3i32( 4, 5, 6);
v3i32 c = a + b;
}


Line 3 might use the 2d addition operator instead of the 3d addition operator. In this case:

c.x = a.x + b.x;
c.y = a.y + b.y;
c.z = a.z; (incorrect)


My question basically boils down to: How do I restrict the scope of my operator templates so that "class A" only ever substitutes a kv2 (where kv2 is a templated struct). Do I place the operator inside the kv2 template definition, or outside it, and either way, what is the correct syntax.

BTW, is this beginner-level templates (ie, I''m in the wrong forum)?

Share this post


Link to post
Share on other sites
civguy    308

      
template <typename I>
inline kv2<I> operator + (kv2<I> a, kv2<I> b) {
a.x += b.x;
a.y += b.y;
return a;
}

template <typename I>
inline kv2<I> operator * (kv2<I> a, I n) {
a.x *= n;
a.y *= n;
return a;
}

edit, edit.. I didn't think enough again.

Anyway, let your operators return a const object so that this wouldn't be possible:

(a * 5) = c;

And the + operator's second argument could be a const reference instead of passed by value.

[edited by - civguy on October 31, 2002 9:19:01 AM]

Share this post


Link to post
Share on other sites