我必须为我制作的一些非常复杂的对象重载基本的算术运算符。到目前为止,我已成功实施operator*
;现在我需要operator+
等。operator*
的代码非常大,但operator*
和operator+
之间的唯一区别是我使用{{1}的一行在某些复数上代替+
。这一行将在一个被多次调用的循环内部,所以我希望它有效,这似乎意味着没有函数指针。 (如果我错了,请纠正我。)
这似乎是模板的完美用法。但我对正确的语法感到茫然。我在*
类定义中想到这样的事情:
ComplicatedObject
这个问题是相关的:"function passed as template argument"。但作为模板参数传递的函数不是运算符。
我已经用我能想到的各种方式摆弄了语法,但编译器总是抱怨语法错误。我该怎么做?
为清楚起见,我在上面的代码中包含了完整的解决方案,以及人们可能需要的其他概括:
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);
}
答案 0 :(得分:4)
我认为std::plus<std::complex>
和std::multiplies<std::complex>
是你正在寻找的,但我并不是100%确定我理解你的问题(是你在没有向我们展示的课程中的代码片段) ?)
答案 1 :(得分:1)
您有两种选择。在运行时传递函数:
#include <functional>
template <typename ComplexBinaryOp>
ComplicatedObject BinaryOp(const ComplicatedObject& B, ComplexBinaryOp op) const {
// ...
C.f[i] = op(f[i], B.f[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 another floating-point type
typedef double (*ComplexBinaryOp)(double, double);
template <ComplexBinaryOp op>
ComplicatedObject BinaryOp(const ComplicatedObject& B) const {
// ...
C.f[i] = op(f[i], B.f[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);
我相信你也可以通过改变ComplexBinaryOp
的定义来对成员函数指针做同样的事情。