用c ++设计点积运算符

时间:2013-12-31 17:42:56

标签: c++ operator-overloading

我希望能够写出a = b.c之类的语句;其中b和c是std :: vector,a是它们的标量点积(double)。为此,我应该将点积运算与'。'联系起来。符号。这可能吗?

4 个答案:

答案 0 :(得分:6)

您无法覆盖点运算符(.)。

而且,即使你可以永远不应该为此目的。覆盖运算符时,您应遵循以下三个规则:

  1. 如果操作员的意思是暧昧的,则不应该超载。
  2. 始终遵循运营商众所周知的语义。
  3. 始终为相关操作员组的所有提供重载。
  4. 您的设计违反了第二条规则:您希望彻底更改点运算符的语义。

    您应该提供自己的功能来执行点操作,而不是这样做。

答案 1 :(得分:2)

this link。我认为定义一个dot()函数比重载“。”要好得多。点符号具有非常特定的功能,你真的会通过重载它来寻找麻烦(如果你可以的话)

答案 2 :(得分:0)

'。'符号不能超载,它有一个固定的含义。另外,要向std :: vector添加一个点积(虽然我不建议这种方法),你需要从std :: vector创建一个新的派生类。相反,我建议创建自己的矢量类,或找到现有的矢量类。

这是关于设计一个好的c ++矢量类的一些建议的博客文章。 http://www.reedbeta.com/blog/2013/12/28/on-vector-math-libraries/

答案 3 :(得分:0)

虽然C ++ .运算符不能重载,但您可以创建类似的内容。

#include <iostream>
#include <vector>
#include <utility>

首先,描述您要执行的操作的函数dot_product。请原谅我,如果我过于通用:

template<typename T, typename U, typename A1, typename A2>
decltype(std::declval<T>() * std::declval<U>() + std::declval<T>() * std::declval<U>())
dot_product( std::vector<T, A1> const& lhs, std::vector<U, A2> const& rhs )
{
  typedef decltype(std::declval<T>() * std::declval<U>()) product_type;
  typedef decltype( std::declval<product_type>() + std::declval<product_type>()) return_type;
  return_type sum = 0;
  for( std::size_t i = 0; i < lhs.size() && i < rhs.size(); ++i ) {
    sum += lhs[i] * rhs[i];
  }
  return sum;
}

接下来,一些允许我们使用中缀表示法的样板:

template<typename LHS>
struct half_dot {
  LHS lhs;
  half_dot( LHS&& lhs_ ):lhs(std::forward<LHS>(lhs_)) {}
  template<typename RHS>
  decltype( dot_product( std::declval<LHS>(), std::declval<RHS>() ) )
  operator*( RHS&& rhs ) const {
    return dot_product( std::forward<LHS>(lhs), std::forward<RHS>(rhs) );
  }
};
struct dot_t {};
template<typename LHS>
half_dot<LHS> operator*( LHS&& lhs, dot_t ) {
  return {std::forward<LHS>(lhs)};
}
static dot_t dot;

最后,使用它的一个例子:

int main() {
  std::vector<int> foo = {1,2,3};
  std::vector<int> bar = {3,2,1};
  std::cout << (foo *dot* bar) << "\n";
}

live example

您可以重载dot_product以执行任何操作,A *dot* B将调用dot_product( A, B )并在执行上述样板后返回结果。