Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ template question

Started by Mayrel Oct 30, 2004 at 11:33 AM 2 replies 950+ views
Original Post
Mayrel
Mayrel
The question is in the code.

template<unsigned int SIZE>
class Vector {
public:
  Vector () {
    for (int i = 0; i < SIZE; ++i)
      array = 0;
  }
  Vector (float f) {
    for (int i = 0; i < SIZE; ++i)
      array = f;
  }
  const float& operator[] (int index)) const {
    return array[index];
  };
  float& operator[] (int index)) {
    return array[index];
  };
private:
  float array[SIZE];
}

template<>
struct Vector<3> {
  Vector (float x, float y, float z) {
    array[0] = x;
    array[1] = x;
    array[2] = x;
  }
  // Is it possible to import the definitions of the
  // unspecialised version of Vector<3> into this one?
  // Or do I have to duplicate the code?
}

Polymorphic OOP
Polymorphic OOP
Nope, not possible. However, there are alternatives. For instance, you can have your vector type actually internally inherit from another type. That base type has the common functions to all specializations. Then, just specialize the child class. This way you don't have to duplicate code since the common code is in the base.

Another thing you can do is to have no external specialization and just have the constructor call the proper initialization function based on a metaprogramming condition (IE using boost::_if to yield a type with the appropriate static initialization function).

Also, if you just want to get rid of the for loops, you can use metaprogramming instead.
silvermace
silvermace
i'm not sure using any kind of polymorphism for a vector class is good, mainly because it can cause problems later down the track, i'll try to explain why.

when you have virtual methods and a (for example) vector3 which derives from the base, you might (in some cases) inadvertantly pass it as a pointer to some API function or do some pointer arithmatic on it thinking its sizeof() is 12 (3 floats), when infact the inherited one may contain a VF table.

to demonstrate my point better than my poor explinational skills:
// base class for vectorclass vector_base {	public:			virtual const float *fooBar() const = 0; //pure virtuality};// inherited vectorclass inherited_vector3 : public vector_base {	public:		float data[3];		virtual const float *fooBar() const { return data; }};// basic vanilla vector structstruct basic_vector3 {	float data[3];        const float *fooBar() const { return data; }};int main() {	cout << "sizeof inherited_vector3: " << sizeof(inherited_vector3) << endl;	cout << "sizeof basic_vector3: " << sizeof(basic_vector3) << endl;	return 0;}

prints the output:
sizeof inherited_vector3: 16sizeof basic_vector3: 12


Just some advice about polymorphism in C++..
-Danu
snk_kid
snk_kid
Quote:
Original post by silvermace
i'm not sure using any kind of polymorphism for a vector class is good, mainly because it can cause problems later down the track, i'll try to explain why.

when you have virtual methods and a (for example) vector3 which derives from the base, you might (in some cases) inadvertantly pass it as a pointer to some API function or do some pointer arithmatic on it thinking its sizeof() is 12 (3 floats), when infact the inherited one may contain a VF table.


What Polymorphic OOP was describing wasn't about using polymorphipsm or virtual methods in any way, you can extend concreate types so you can re-use code from the base, you have your generic n-vector then extend for a 3d vector, if you compare the generic n-vector given with 3 and the extended 3d vector version there sizes will be the same what i mean is:

#include <cstddef>#include <algorithm>template < size_t N >struct Vector {   typedef size_t size_type;private:   static const size_type _size = N;   float n[_size];public:  Vector(float def_value = 0.0f) {    std::fill(n, n + _size, def_value);  }  const float& operator[](size_type index) const {      return n[index];  }  float& operator[] (size_type index) {      return n[index];  }};struct Vector3 : Vector<3> {   Vector3(float x = 0.0f, float y = 0.0f, float z = 0.0f)  {      (*this)[0] = x, (*this)[1] = y, (*this)[2] = z;   }};#include <iostream>int main() {   Vector<3> v1;   Vector3 v2;   std::cout << std::boolalpha << (sizeof(Vector<3>) == sizeof(Vector3)) << std::endl;   std::cout << std::boolalpha << (sizeof(v1) == sizeof(v2)) << std::endl;}


evaluates to true.

@Mayrel: to be honest if your not going to be using arbitrary sized vectors & matrices i think your wasting your time because if you do need to use then your better off using one of the expression template libraries out there for arbitrary sized vectors & matrices.

[Edited by - snk_kid on October 31, 2004 4:06:09 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.