Firing back...
//Operator+ (refactored to trip up JPs)
MyObject operator+(MyObject lhs, MyObject const& rhs) {
return lhs += rhs;
}
Firing back...
//Operator+ (refactored to trip up JPs)
MyObject operator+(MyObject lhs, MyObject const& rhs) {
return lhs += rhs;
}
Firing back...
//Operator+ (refactored to trip up JPs) MyObject operator+(MyObject lhs, MyObject const& rhs) { return lhs += rhs; }
matA = (1.0f / det()) * matA;
matA = matA * (1.0f / det()); // Compiler is happy
matA = (1.0f / det()) * matA; // Compiler gets sad
The compiler doesn't assume your operator is commutative. If you want it to be, you'll need to define both operators (to do the exact same thing).
You could have some function templates supply all combinations of * for all classes providing a *=, so you would only need to write those once.
You could have some function templates supply all combinations of * for all classes providing a *=, so you would only need to write those once.
See <boost/operators.hpp>.
Edit: I hate their example, where they define the sum point + point. It is OK to define point + vector and vector + vector, but point + point should not compile.
//In header
MyObject MyObject::operator+(const int num);
MyObject MyObject::operator+(const int num, const MyObject &obj);
//In CPP
MyObject MyObject::operator+(const int num)
{
MyObject tmp;
tmp.val = val + num;
return tmp;
}
MyObject MyObject::operator+(const int num, const MyObject &obj)
{
return obj + num;
}
I know nothing about template classes, but I was thinking I could just do something like this:
//In header
MyObject MyObject::operator+(const int num);
MyObject MyObject::operator+(const int num, const MyObject &obj);
//In CPP
MyObject MyObject::operator+(const int num)
{
MyObject tmp;
tmp.val = val + num;
return tmp;
}
MyObject MyObject::operator+(const int num, const MyObject &obj)
{
return obj + num;
}
I think I get what you're saying, but there are some problems here. You should prefer that any function that can be implemented as a non-member, non-friend function should be implemented as exactly that. This is the case for the canonical pattern of implementing +, -, *, / in terms of member functions +=, -=, *=, /=. Sometimes you can even implement += as non-member, non-friend when the data is public, but as this is a rare circumstance I prefer to always leave them as members myself, for consistency if nothing else.
The pattern should look something like this:
// member function operator *=
MyObject& MyObject::operator*=(const MyOtherObject &rhs)
{
this.stuff *= rhs.myotherstuff;
return *this;
}
// non-member, non-friend operator * (outside the class, but inside the same namespace)
MyObject operator*(MyObject lhs, const MyOtherObject &rhs)
{
return lhs *= rhs;
}
// and the commutative version
MyObject operator*(const MyOtherObject &lhs, MyObject rhs)
{
return rhs *= lhs;
}
Note that you have to follow the types, reference-ness vs. Value-ness, and const-ness of parameters and return values to get exactly what's going on. But aside from being better practice than just sticking everything inside the class, this form is also something that should clue the compiler in that it can implement the return value optimization (though, compilers are pretty capable of picking up on it in other relevant circumstances today, especially post C++11).