Skip to main content
gamedev.net
🔒 Locked

Template classes and conversion operators

Started by Wavarian Dec 20, 2004 at 4:32 AM 10 replies 850+ views
Original Post
Wavarian
Wavarian
Greets guys, I doubt this is possible, however does anyone know how to achieve the intended result? (Broken code example below)

template <typename T>
class CTemp {

	T x,y;

public:

	CTemp() {}
	CTemp(T x,T y) {

		this->x = x;
		this->y = y;
	}

	// ...

	CTemp<T> operator +(const CTemp<T> &obj) const {

		return CTemp<T>((x + obj.x),(y + obj.y));
	}

	// ...
};


void Main() {

	CTemp<int> temp1(5,5);
	CTemp<float> temp2(1.0f,1.0f);

	// Clearly won't work since no conversion
	// operators have been specified, but how
	// (if possible) to specify them?

	temp1 = temp1 + temp2;
}

darookie
darookie
You would need to define a '+' operator that is templated:
template<typename R, typename T1, typename T2>CTemp<R> operator + (const CTemp<T1> &t1, const CTemp<T2> &t2) {    return CTemp<R>(R(t1.x + t2.x), R(t1.y + t2.y));}


Something along that line, I guess.
SiCrane
SiCrane
Alternately you can define a templated constructor

	template <typename U>	CTemp(const CTemp< U > & other) : x(other.x), y(other.y) {}


or conversion operator

	template <typename U>	operator CTemp< U >() { return CTemp< U >(x, y); }


But of course, in general, implicit conversions are a PITA, so use with caution.
joanusdmentia
joanusdmentia
Quote:
Original post by darookie
You would need to define a '+' operator that is templated:
*** Source Snippet Removed ***

Something along that line, I guess.

Will that work? I didn't think compilers were able to deduce template parameters from the return type.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
darookie
darookie
A good compiler will be able to deduce template arguments if no ambiguous types are involved, e.g. CTemp and CTemp will not work, while float and int will.
joanusdmentia
joanusdmentia
Yes, but deducing by return type? The following fails in VC++ 7.1

template<typename R, typename T1, typename T2>R testfunc(T1 a, T2 b){    return R(a+b);}void func(){    double r = testfunc(1.0f,2);}


error C2783: 'R testfunc(T1,T2)' : could not deduce template argument for 'R'
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
Wavarian
Wavarian
That's a first =x

The above poster was me of course.
darookie
darookie
joanusdmentia:
Jep. It's because you must make the constructor explicit.
E.g.
template<typename T>class CTok {   T t;public:   explicit CTok(T s) : t(s)   {}};template<typename R, typename T1, typename T2>R testfunc(T1 a, T2 b){    return R(a+b);}void func(){    CTok<double> r(testfunc<double>(1.0f,2));}int main() {  func();  return 0;}

Compiles fine.
[edit]
joanusdmentia:
The reason is, that double x = whatever is still ambiguous, since any integer and float type can be implicitly converted to a double. Hence the compiler cannot know whether you want this conversion or an explicit assignment of the same type.

Wavarian:
You can use template specialisation for this.
Also I don't see much overhead with the additional operators, at least not for the arithmetical ones since CTemp<> instances would have to define them anyway. It is also a good idea to manually define the assignment operator, too. It will save you from a lot of problems if your classes contain dynamically allocated data or resource handles.
[/edit]
joanusdmentia
joanusdmentia
But then the compiler isn't deducing R, you're explicitly specifying it. But when you have
CTemp<int> a;CTemp<float> b;CTemp<double> r = a+b;

you can't explicitly specify a template parameter on the + operator.... well, not with explicitly calling operator+(a,b).

EDIT: In particular, the following doesn't work
template<typename T>struct CTemp {   T x,y;   CTemp(T x=0, T y=0) : x(x), y(y) {}};template<typename R, typename T1, typename T2>CTemp<R> operator+(CTemp<T1> a, CTemp<T2> b){    return CTemp<R>(R(a.x+b.x),R(a.y+b.y));}void func(){    CTemp<int> a;    CTemp<float> b;    CTemp<float> r = a+b;}

Which is what I though you were suggesting to the OP.

[Edited by - joanusdmentia on December 20, 2004 5:19:17 AM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
darookie
darookie
joanusdmentia: The code you posted cannot work. The reason, however, has nothing to do with templates [wink].
template<typename T>struct CTemp{   T x,y;   template<typename U>   CTemp<T> operator + (const CTemp &r) const {         CTemp<T> v;         v.x = r.x + x;         v.y = r.y + y;         return v;   }};void func(){    CTemp<int> a;    CTemp<float> b;    CTemp<float> r = a + b; // <- won't work    CTemp<float> s = b + a; // <- will work}

Ahh, the joy - C++ templates [smile]

[edit]
I also didn't suggest a working solution and never stated that. I was just providing a hint on how the problem could be solved. If it looked like I was posting a working solution, then I apologise for the confusion.
[/edit]
Wavarian
Wavarian
I would like to thank both darookie and SiCrane. Template specialisation was exactly what I was looking for. Ratings given.

Cheers.

Topic Locked

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

Sign in to reply to this topic.