This forum has been archived. All content is frozen. Please use KDE Discuss instead.

partial template typedefs for Vector3 etc (code migration)

Tags: None
(comma "," separated)
eudoxos
Registered Member
Posts
36
Karma
0
Hi,

I'm migrating http://www.yade-dem.org from WildMagic3 library to Eigen. I would like to keep source code compatibility during transition period to check that results are equal and so on.

Wm3 uses Vector3, Matrix3 and few other classes templated on ScalarType. Eigen::Matrix has that as first argument, but it is not possible to create template typedef without specifying all template arguments (like template<typename ScalarType> typedef Eigen::Matrix<ScalarType,3,1> Vector3).

Most of the code actually uses specialized types (Vector3r, Matrix3r), but some functions are still templated on ScalarType.

I know there is template alias feature in c++0x, but gcc doesn't support it unfortunately in 4.5.

Can someone suggest workarounds? Note that we have local copy of parts of Wm3 we need in the tree and are free to modify it in any way. (For instance, we could (?) create fake Wm3::Matrix class and then replace all Vector3<int> by Wm3:Matrix<int,3,1> to make it compatible with Eigen; but that would be rather complicated and I don't see as far as to foresee possible troubles with specialization of functions afterwards).

Thanks everybody.

Vaclav
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
I suggest you to us a small template helper struct you would use like this:

Vector3<X,Y,Z>

becomes:

typename GetVector3<X,Y,Z>::Type

(the typename is only needed if X or Y or Z is a template parameter as well.

Implementing struct GetVector3 for Eigen or WM3 is straightforward.
eudoxos
Registered Member
Posts
36
Karma
0
Hi Gael, thanks for your suggestion. I actually tried it, but there is still some problem with finding templated functions:
Code: Select all
template<typename ScalarType> struct Vector3{ typedef Eigen::Matrix<ScalarType,3,1> type; };
typedef Vector3<Real>::type Vector3r;
/* ... */
template<typename ScalarType> typename Vector3<ScalarType>::type componentMaxVector(typename Vector3<ScalarType>::type& a, typename Vector3<ScalarType>::type& b){ return typename Vector3<ScalarType>::type(std::max(a.x(),b.x()),std::max(a.y(),b.y()),std::max(a.z(),b.z()));}
/* ... */
Vector3r a,b,c;
// some values assigneed to a,b
c=componentMaxVector(a,b);

which gives me
Code: Select all
error: no matching function for call to 'componentMaxVector(Vector3r&, Vector3r&)'

What is wrong? Why is the function not being found?
eudoxos
Registered Member
Posts
36
Karma
0
OK, apparently it would be necessary to say
Code: Select all
template<typename ScalarType> typename Vector3<ScalarType>::type componentMaxVector(typename Eigen::Matrix::<ScalarType,3,1>& a, typename Eigen::Matrix::<ScalarType,3,1>& b){ return typename Vector3<ScalarType>::type(std::max(a.x(),b.x()),std::max(a.y(),b.y()),std::max(a.z(),b.z()));}

so that the compiler picks up the function. That would however defeat the purpose of source-compatibility.

My final solution is via macros ;-):
Code: Select all
#ifdef YADE_EIGEN
   #define VECTOR3_TEMPLATE(Scalar) Eigen::Matrix<Scalar,3,1>
#else
   #define VECTOR3_TEMPLATE(Scalar) Wm3::Vector3<Scalar>
#endif
// templated functions like this
template<typename Scalar> VECTOR3_TEMPLATE(Scalar) componentMaxVector(const VECTOR3_TEMPLATE(Scalar)& a, const VECTOR3_TEMPLATE(Scalar)& b){ return VECTOR3_TEMPLATE(Scalar)(std::max(a.x(),b.x()),std::max(a.y(),b.y()),std::max(a.z(),b.z()));}
// normal code with typedefs
typedef VECTOR3_TEMPLATE(Real) Vector3r;

ugly but works.

Thanks for your suggestions.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
indeed, for templated function arguments, this does not work... I don't see anything really better than macros, sorry.


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Sogou [Bot]