How to design a vector class to use any sqrt function?

Started by
23 comments, last by johnstanp 15 years, 9 months ago
Well, the title says it all. I was just wondering how it could be possible to "assign" a sqrt function to a Vector class, in order to parametrize the norm( or its inverse ) computing inside the class? My vector class is a template one, and one possible sqrt algorithm is a static function inside a math class( also a template one ). So I have:

template<typename T>
class Vector3
{
       public:
              ...
              T length()const;

       private:
               T x_[3];
};

template<typename T>
class Math
{
       public:
              ...
              static Real sqrt( const Real& )const
};


I want to be able to make the length function use the standard std::sqrt() or my sqrt function or any other one. Sorry if my english is not good enough... [Edited by - johnstanp on July 7, 2008 5:26:57 PM]
Advertisement
Here's an interesting idea.

It uses compile-time evaluation to determine the value.

While it says for integers, I don't see any real reason why it wouldn't work for any data type.


As for sqrt() function, you can't, that one can only be evaluated during run-time.
Quote:Original post by Antheus
Here's an interesting idea.

It uses compile-time evaluation to determine the value.

While it says for integers, I don't see any real reason why it wouldn't work for any data type.


As for sqrt() function, you can't, that one can only be evaluated during run-time.


Interesting, but that function can only be used for integers?

Maybe my use of the term "compile time" is not appropriate: I just want to implement a general enough method that would give me the possibility to use inside my class any sqrt algorithm. I was just thinking of functors but I wanted to know if there were better or more elegant ways to achieve that.

PS:I'll change the title of the topic...to make it less specific.
Quote:Original post by johnstanp
I want to be able to make the length function use the standard std::sqrt() or my sqrt function or any other one.

#include <cmath>#include <iostream>template <typename T, T (*SQRT)(T)>struct Vec3{	T x, y, z;		T length() const {		return SQRT(x*x + y*y + z*z);	}};typedef Vec3<float, std::sqrt> Vec3Std;int main(){	Vec3Std v = {1, 2, 3};		std::cout << v.length() << std::endl;}

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

If i understand you correctly you want something like this:


template<typename T, typename Math>class Vector3{	public:		...		T length()const		{			// blabla			Math::sqrt(5.0);		}			private:		T x_[3];};class StdMath{public:	static float sqrt(float x)	{		return std::sqrt(x);	}};// Vector using stdtypedef Vector<float, StdMath> StdVector;
Quote:Original post by swiftcoder
Quote:Original post by johnstanp
I want to be able to make the length function use the standard std::sqrt() or my sqrt function or any other one.

*** Source Snippet Removed ***


Thank you for being so quick to reply...I'll implement it.
Will it work for my function template<typename T> T Math<T>::sqrt( const T& )?
Quote:Original post by johnstanp
Quote:Original post by Antheus
Here's an interesting idea.

It uses compile-time evaluation to determine the value.

While it says for integers, I don't see any real reason why it wouldn't work for any data type.


As for sqrt() function, you can't, that one can only be evaluated during run-time.


Interesting, but that function can only be used for integers?


Yeah, unless you extend it to rationals. Alternatively you could look at D, which has support for floats as template parameters. Most of the time, there's not much benefit to this.

Quote:Maybe my use of the term "compile time" is not appropriate: I just want to implement a general enough method that would give me the possibility to use inside my class any sqrt algorithm. I was just thinking of functors but I wanted to know if there were better or more elegant ways to achieve that.

PS:I'll change the title of the topic...to make it less specific.



You could use a traits mechanism:

namespace calc_traits{template<typename T>struct sqrt{    static T calc(T x) { return std::sqrt(x); }};} // close namespace


Call calc_traits::sqrt<T>::calc(number) to get the square root of number, which should be a T. Use template specialisation to add support for your custom types (or other peoples custom types):

namespace calc_traits{template<>struct sqrt<big_num>{    static big_num calc(const big_num &x) { /* custom implementation */ }};} // close namespace
Quote:Original post by lexs
If i understand you correctly you want something like this:


*** Source Snippet Removed ***


That's it!

Quote:Original post by the_edd

You could use a traits mechanism:

namespace calc_traits{template<typename T>struct sqrt{    static T calc(T x) { return std::sqrt(x); }};} // close namespace


Call calc_traits::sqrt<T>::calc(number) to get the square root of number, which should be a T. Use template specialisation to add support for your custom types (or other peoples custom types):

namespace calc_traits{template<>struct sqrt<big_num>{    static big_num calc(const big_num &x) { /* custom implementation */ }};} // close namespace


I had problems understanding the traits mechanism which I thought was related to type information...I understand the method, and I think that I could combine it with what I have in mind. Actually, I understand there's a special syntax for specifying pointers to member functions and there's a possibility to instanciate a class using such a pointer. I'll search the correct syntax.
Quote:Original post by johnstanp
I had problems understanding the traits mechanism which I thought was related to type information...

It usually is used for that, but that's not the heart of the concept. Traits allow you to use 3rd party code with yours without changing the 3rd party implementation. Concept maps in the next revision of the standard takes this idea even further.

The other plus of this is that you don't need to add an extra warty template parameter to your vector class.

This topic is closed to new replies.

Advertisement