8

对于我制作的一些非常复杂的对象,我必须重载基本算术运算符。到目前为止,我已经成功实施operator*;现在我需要operator+,等等。 的代码非常大,但和operator*之间的唯一区别将是我使用的一行而不是一些复数。这条线将在一个被多次调用的循环内,所以我希望它高效,这似乎意味着没有函数指针。(如我错了请纠正我。)operator*operator++*

这似乎是模板的完美用途。但我不知道正确的语法。我在ComplicatedObject类定义中想这样的事情:

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);
}

这个问题是相关的:“作为模板参数传递的函数”。但是作为模板参数传递的函数不是运算符。

我已经用我能想到的各种方式摆弄了语法,但是编译器总是抱怨语法不好。我该怎么做?

编辑:

为了清楚起见,我在上面的代码中包含了完整的解决方案,以及人们可能需要的其他概括:

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);
}
4

2 回答 2

4

我认为std::plus<std::complex>并且std::multiplies<std::complex>是您正在寻找的东西,但我不是 100% 确定我理解您的问题(您的代码片段是否在您没有向我们展示的课程中?)

于 2013-06-26T04:00:18.297 回答
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.

于 2013-06-26T04:04:36.870 回答