The transfer operator as a parameter to the function template

I need to overload the basic arithmetic operators for some very complex objects that I made. So far, I have successfully implemented operator* ; now i need operator+ etc. The code for operator* 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 a loop that gets called many times, so I want it to be efficient. which, it would seem, did not imply any function pointers. (Correct me if I am wrong.)

It seems like the perfect use of patterns. But I'm at a loss regarding the correct syntax. I think of this in the definition of the ComplicatedObject class:

 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: Cf[i] = ComplexBinaryOp(f[i], Bf[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 functions passed as template arguments are not operators.

I searched the syntax every time I can think of, but the compiler always complains about bad syntax. How can I do it?

Edit:

For clarity, I include a complete solution in terms of my code above, as well as additional generalizations that people might 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: Cf[i] = ComplexBinaryOp()(f[i], Bf[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); } 
+7
source share
2 answers

I think std::plus<std::complex> and std::multiplies<std::complex> are what you are looking for, but I'm not 100% sure, I understand your question (this is your code snippet in a class that you don’t show us?)

+4
source

You have two options. Pass the function at runtime:

 #include <functional> template <typename ComplexBinaryOp> ComplicatedObject BinaryOp(const ComplicatedObject& B, ComplexBinaryOp op) const { // ... Cf[i] = op(f[i], Bf[i]); // ... } // functor wrapping member function pointer BinaryOp(B, std::mem_fn(&std::complex<double>::operator+)); // standard-issue functor BinaryOp(B, std::plus<std::complex<double>>()); 

Or pass it at compile time:

 // or another floating-point type typedef double (*ComplexBinaryOp)(double, double); template <ComplexBinaryOp op> ComplicatedObject BinaryOp(const ComplicatedObject& B) const { // ... Cf[i] = op(f[i], Bf[i]); // ... } // non-member function template<class T> std::complex<T> add_complex(const std::complex<T>& a, const std::complex<T>& b) { return a + b; } // non-member function pointer BinaryOp<add_complex<double>>(B); 

I believe that you can do the same with member function pointers by changing the definition of ComplexBinaryOp .

+1
source

All Articles