I have a situation where I have math operations that make sense to overload for convenience.
But some of them operate on other types.
Like
vec3<type> * type
and
type * vec3<type>
One way for the right hand argument for a scalar is:
template<class T, class SubT>
class Vec3 {
// this is fine, ie: works
SubT operator *(const T &val) {
return(SubT(x*val,y*val,z*val));
}
};
Ive read that is is best only to implement operators for *, +, -, /, etc "out of class" or let the compiler deduce things from the += version in the class.
- is this optimal vs having + implemented in the class?
- how does one do this for the reverse where the left hand argument is the other type?
Ie in my particular case, the templated operator has two template type arguments. One is the type of the element, and the other is the super class the template is implementing it's methods for.
template<class T, class SubT>
SubT operator *(const T &a, const Vec3Base<T, B> &b) {
return(b * a);
}
Anyway hopefully you get my desire, how to do it properly is the question :)
Like do I need to only make to take one type ? ie: the vector type, and then get the element type from it as a typedef ??
template<class VT>
VT::SubT operator*(const VT::ElemT &a, const VT &v) {
return(v * a);
}
and should I also implement the other way instead of in the class but "out of class" with:
template<class VT>
VT::SubT operator*(const VT &a, const VT::ElemT &b ) {
return(VT::SubT(a.x*b,a.y*b,a.z*b));
}
Well I did read most of the answers in the idioims for operator overloading question.
I does answer a lot of things. BUT doesn't cover the ramafacations for templates and templates declaring operators used in the subclasses of those templates.
For all operators where you have to choose to either implement them as a member function or a non-member function, use the following rules of thumb to decide:
This was somewhat helpful in my desire to know the best way to implement whether out of class or in the class.
If it is a unary operator, implement it as a member function. If a binary operator treats both operands equally (it leaves them unchanged), implement this operator as a non-member function. If a binary operator does not treat both of its operands equally (usually it will change its left operand), it might be useful to make
it a member function of its left operand’s type, if it has to access the operand's private parts.
I was wondering if there is an issue regarding prioritization of one over the other for templates. I find if an operator is declared in a template and it is a superclass of a subclass that inherits it's operators at least in the MS compiler it will prioritize looking at the global one over the one in the supreclass. Nasty !!! similar issues happen with clang and gcc.
I did find I really have to declaare all the possible conflicting operators at the same level so the overload resolution works as expected. ie: all in the same superclass of the subclass, if there are poerators declared in a superclass of the superclass, they will sometimes be ignored it seems if there is some wayward conversion that supplies an argument to one of the overloads at the higher priority ( arrrgh ).
It seems at this point I have resolved all the compile issue - now to get it to link hahaha !!