Template vs. float/double datatype

Hi all

I am writing a vector 3 class. Since I would like to make it able to work on several numerical data types (including floats, doubles, among others) I decided to use templates.
Below is an excerpt of Vector3Sw class and the multiplication by an scalar operator that I've written (everything stored in a separate header file):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     template <class T> class TVector3Sw
     {
     public:
        T e[3];
        ...
        TVector3Sw<T>& operator *= (const T& rhs);
        ...
     }
     ...
     template <class T> inline TVector3Sw<T> operator * (const TVector3Sw<T>& lhs, const T& rhs)
     {
        return TVector3Sw<T>(lhs) *= rhs;
     }
     ...
     


The operator * is not a method of Vector3Sw class neither its friend, since it does not use private/protected members of the Vector3Sw.
The main program contains:

1
2
3
4
5
6
7
8
9
10
11
     typedef TVector3Sw<double> TVector3;

     int main(void)
     {
        TVector3 a(1,2,3), b(4,5,6), c;

        c = a * 2.0f;

        return 0;
     }
     


I use the typedef to be able to switch among different data types (float, double, etc.) and also switch among different vector 3 implementations (e.g. I plan to test a possibly higher performance vector 3 class based on SSE2,3, etc.).
That said, when I try to compile the code I end up with:

1
2
3
4
5
g++ -c -o main.o -g -DUNIX -DDEBUG -I/usr/include -I/usr/ -I/usr/local/include -DGLX_GLXEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES -DUNIX -I. -I./ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:10: error: no match foroperator*’ in ‘a * 2.0e+0f’
make: *** [main.o] Error 1
     


I thought that float or double constants would be automatically converted to the type used by the Vector3Sw template.
I could fix this problem by creating two versions of the opertor *, one using float and the other using double, instead of using T:

1
2
3
4
5
6
7
8
9
     template <class T> inline TVector3Sw<T> operator * (const TVector3Sw<T>& lhs, const float& rhs)
     {
        return TVector3Sw<T>(lhs) *= rhs;
     }
     template <class T> inline TVector3Sw<T> operator * (const TVector3Sw<T>& lhs, const double& rhs)
     {
        return TVector3Sw<T>(lhs) *= rhs;
     }
     


However, there are additional possibilities for the data type (e.g. long double), and since the reason for using templates is to avoid rewriting code just because the data type has changed, I would like to know if it is possible to solve this problem in a more elegant way, using only the T generic type.

My system is Ubuntu Linux 10.10, gcc version 4.4.5.

Thank you in advance and a Happy New Year !!! :)
Christian
Try template <class T, class U> vector<T> operator * (vector<T>, U);
Do the same for *=. The conversion will then be made in the innermost layer.
Last edited on
Hi Hamsterman

Your solution worked!
The only point is that it was not necessary to make the same change for the *= operator. I will investigate the reason for this later (the operator *= is part of the TVector3Sw class, and adding the second template parameter U for the *= operator implies that a broader change has to be made to the class... ).

Thank you very much!
Christian

I guess when * is not a part of the class, the compiler can't decide whether to use the first or the second argument to deduce T, and when *= is in the class, it's natural to use the first one.

By the way,
1
2
3
4
5
6
7
template<class T>
class vector{
   ...
   template<class U>
   vector<T> operator *= (U u) { ... }
   ...
};
is perfectly valid, I think..
my code gives me error about "U undeclared " I dont know what i am missing .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class T>
class myvector
{
	private : 
		T a;
	public:
		template<class U>
		myvector<T> operator * (U u);
		T getA() { return a; }
};
template<class T> myvector<T> myvector<T>::operator*(U u)
{
	return a * u.a;
};
You didn't add a template<class U> to the implementation. By the way, template<class T, class U> is not the same as template<class T> template<class U> and it's the latter that you need.
Topic archived. No new replies allowed.