Question:
How to add together classes with different template parameters in C++?
?
2011-10-22 06:00:04 UTC
For example, i made a class called vec2d with template , but if you have a vec2d of int and one of double and you try to add them it gives the error that it doesn't work. Down below is a link to my code. I'm new to templates so if you think this isn't the place for them then it probably isn't and i just want to be able to input different values as parameters in the functions.

http://pastebin.com/BMsk4bNX
Three answers:
Cubbi
2011-10-23 13:45:33 UTC
Since I was brought up, yes, the problem is the choice of the return type: when adding vec2d nad vec2d, you want to return vec2d regardless of the order of addition.



On a sufficiently new compiler, you can use std::common_type:



template

template

vec2d::type> vec2d::operator +(vec2d& rhs)

{

     return vec2d::type>(getX() + rhs.getX(), getY() + rhs.getY());

}



test: https://ideone.com/oX5we



Or decltype on the addition expression:



template

template

vec2d vec2d::operator +(vec2d& rhs) {

     return vec2d(getX() + rhs.getX(), getY() + rhs.getY());

}



(works with gcc 4.6+, ideone is too old for this approach)



If your compiler does not have std::common_type yet, it's very easily implemented, you can grab the implementation from the boost library http://www.boost.org/doc/libs/1_47_0/libs/type_traits/doc/html/boost_typetraits/reference/common_type.html (or just use boost as-is)



PS: please declare your accessors and operator arguments const (Sutter/Alexandrescu Coding Style chapter 15)

PS2: also, make your operators non-member functions (Sutter/Alexandrescu chapter 44)
Ratchetr
2011-10-22 07:52:44 UTC
Here is an implementation of MichaelI's solution:





template

vec2d operator +(vec2d& a,vec2d& b)

{

    return a + vec2d((T)b.getX(), (T)b.getY());

}





But there is something a bit evil about this.

Suppose you have:

vec2d vecd(1.5,2.5);

vec2d veci(2,3);



What is the return type of:

vecd + veci;



It is vec2d, because T will be double, and U will be int. So the return type is vec2d ==> vec2d.



But what is the return type of:

veci + vecd;



It is vec2d, isn't it? Here, T is int, U is double.



So now you have an operator + where a +b != b + a. They aren't even the same type!

Writing an operator + that isn't Commutative is a bad idea.



So what type DO you want operator + to return? vec2d or vec2d?



I would think you would want to follow the same rules that C++ follows when you add an int and a double. The result will be double. So I would think vecd + veci and veci + vecd should both return vec2d



The only way I can think to do it is to provide these 2 operator + functions (and repeat the pattern for the other operators):



template

vec2d operator +(vec2d& a, vec2d& b)

{

    return a + vec2d(b.getX(),b.getY());

}



template

vec2d operator +(vec2d& a,vec2d& b)

{

    return b + a;

}



Not sure that's the best way (or even a good way ;-), my C++ is a bit rusty, to say the least.



Cubbi can probably give a much better answer to this.
MichaelInScarborough
2011-10-22 07:09:40 UTC
The signature for operator+ is:

template

operator +(const &a, const &b);

This transferred to your code would result to the following in case you add identical types:



template

vec2d operator +(const vec2d &a, const vec2d &b);



This would result to the following signature in case of mixed types:

template

vec2d operator +(const vec2d &a, const vec2d &b);

I introduced the following override in order to take out the confusion about

return values. Naturally the programmer has to make sure that the data

type provided satisfies all scenarios the program was desiged for.

vec2d operator +(const vec2d &a, const vec2d &b);


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...