I have to overload the basic arithmetic operators for some very complicated objects I've made. So far, I've successfully implemented operator*
; now I need operator+
, etc. The code for operator*
is very large, but the only difference between operator*
and operator+
will be one line where I use +
instead of *
on some complex numbers. This line will be inside of a loop that gets called many many times, so I want it to be efficient, which would seem to imply no function pointers. (Correct me if I'm wrong.)
This seems like a perfect use for templates. But I'm at a loss as to the correct syntax. I'm thinking something like this inside the ComplicatedObject
class definition:
template <typename ComplexBinaryOp>
ComplicatedObject BinaryOp(const ComplicatedObject& B) const {
// Do lots of stuff
for(unsigned int i=0; i<OneBazillion; ++i) {
// Here, the f[i] are std::complex<double>'s:
C.f[i] = ComplexBinaryOp(f[i], B.f[i]);
}
// Do some more stuff
return C;
}
inline ComplicatedObject operator*(const ComplicatedObject& B) const {
return BinaryOp<std::complex::operator*>(B);
}
inline ComplicatedObject operator+(const ComplicatedObject& B) const {
return BinaryOp<std::complex::operator+>(B);
}
This question is related: "function passed as template argument". But the functions passed as the template arguments are not operators.
I've fiddled with the syntax every way I can think of, but the compiler always complains of bad syntax. How should I do this?
Edit:
For clarity, I include the complete solution in terms of my code above, along with the additional generalizations people may need:
template <typename ComplexBinaryOp>
ComplicatedObject BinaryOp(const ComplicatedObject& B) const {
// Do lots of stuff
for(unsigned int i=0; i<OneBazillion; ++i) {
// Here, the f[i] are std::complex<double>'s:
C.f[i] = ComplexBinaryOp()(f[i], B.f[i]); // Note extra ()'s
}
// Do some more stuff
return C;
}
inline ComplicatedObject operator+(const ComplicatedObject& B) const {
return BinaryOp<std::plus<std::complex<double> > >(B);
}
inline ComplicatedObject operator-(const ComplicatedObject& B) const {
return BinaryOp<std::minus<std::complex<double> > >(B);
}
inline ComplicatedObject operator*(const ComplicatedObject& B) const {
return BinaryOp<std::multiplies<std::complex<double> > >(B);
}
inline ComplicatedObject operator/(const ComplicatedObject& B) const {
return BinaryOp<std::divides<std::complex<double> > >(B);
}