views:

83

answers:

3

In C++ how to tell compiler that Ogre::Vector3 IS_SAME_AS SomeOtherLIB::Vector3 ? I feel that.. in languages like c++ which are not structural typed but there are cases when it makes sense.

Normally as game developer when working with 4+ libraries that provide sort or their own Vector3 implementation. The code is littered with ToOgre, ToThis, ToThat conversion function. Thats a lot of Float3 copying around which should not happen on first place.

Is in C++ or any other languages where we dont have to convert (copying) from one type to another which is essentially the samething. But any solution in C++ as most of the good gamedevs libs are for c/c++.

+12  A: 

If you use templates you can define functions that take any type of argument as long as the necessary operations are defined on that type. Example:

class Foo { void quack() {} };
class Bar { void quack() {} };
class Baz {};

template<typename Duck>
void f(Duck d) {
    d.quack();
}
int main() {
    f(Foo()); // works
    f(Bar()); // works
    f(Baz()); // compile error because Baz does not have a quack method
    return 0;
}
sepp2k
+1 for psuedo ducktyping example
Earlz
+2  A: 

If you are really sure in case of non-virtual structures, you can do a reinterpret_cast. However, it's better to:

  1. do templated wrapper functions as shown by sepp2k
  2. inherit from one of the vectors and add a conversion operator to the other vector
  3. add a separate _cast function that does the conversion
Kornel Kisielewicz
+3  A: 

While it doesn't suit any situation, templates can give you "compile-time duck typing".

Lets say you have two vector types:

struct Vec3A {
    float x, y, z;
};

struct Vec3B {
    float p[3];
};

You can define function templates that hide the implementation how of to get the components:

template<class T> float get_x(const T&);
template<class T> float get_y(const T&);
template<class T> float get_z(const T&);

template<> float get_x<Vec3A>(const Vec3A& v) { return v.x; }
// ...
template<> float get_x<Vec3B>(const Vec3B& v) { return v.p[0]; }
// ...

With such helpers you can now write generic functions that work on both:

template<class T> float length(const T& t) {
    return std::sqrt(std::pow(get_x(t), 2), 
                     std::pow(get_y(t), 2),
                     std::pow(get_z(t), 2));
}

You can also continue by specializing utilities like length() for performance or other reasons, e.g. if a certain vector already has a member function providing you with the length:

template<> float length<Vec3C>(const Vec3C& v) {
    return v.length();
}
Georg Fritzsche