运算符优先级c ++ |计算的确切顺序是什么?

时间:2015-05-08 19:30:48

标签: c++ operator-keyword operator-precedence

我正在尝试编写一个矩阵计算器,并遇到了一个难题。如果我有A = B*C,则使用我的重载B*C评估operator*(const Matrix&),其中我需要一些临时对象来进行计算。这很好用。但是一旦我遇到更复杂的东西,我需要更多的临时对象,显然我不想手工做/有混合。

说我想评估:

Matrix A = B*C + D*E*F + G*H;

然后运算符优先级告诉我,*将首先被评估。所以:

Step 1) B*C -> t1
Step 2) D*E -> t2
Step 3) t2*F-> t3
Step 4) G*H -> t4
Step 5) t1+t2 -> t5
Step 6) t5+t4 -> t6
Step 7) A=t6

这是确切的顺序吗?或者订单是否具有确定性?我的想法是创建一个链表,我将检查我的+和*,如果正在计算的对象(例如t2 * F)是临时的,那么我可以删除它们/适当插入。

3 个答案:

答案 0 :(得分:2)

Expression templates可以解决这个问题。例如

Matrix M = 2*(A+B) + C;

通常会为A+B2*(A+B)2*(A+B) + C创建3个临时对象。因此,当Matrix对象是重量级时,这可能会效率低下。

表达式模板是一种模板元编程技术,其中运算符被实现为使得它们返回表示整个表达式的对象,但仅在结束时计算表达式。

所以2*(A+B) + C会产生类似

的类型的对象
sum<multiple<float, sum<Matrix, Matrix>>, Matrix>

能够在不分配中间矩阵的情况下计算M。 (在这种情况下,通过分量加法和乘以常数)。该对象本身是在零运行时开销时生成的。

因为这很复杂,所以最好使用线性代数库,例如Eigen

答案 1 :(得分:0)

运算符优先级告诉您将评估哪些订单。它会告诉您每个运算符的操作数。

评估顺序的唯一保证是必须在操作员操作之前评估操作员的操作数。

要查看更简单的示例2 + 3 * 4,优先级表示添加到2的内容为3 * 4,而不是3

在您的示例B*C + D*E*F + G*H中,唯一的保证是:

    在第二个G*H 之前评估
  • + 在第一个B*C
  • 之前评估
  • +D*E*F
  • 之前评估
  • +
  • 在第二个+
  • 之前评估第一个+
  • D*E*F内,第一个*在第二个*之前进行评估。

可能的排序可能是:

(1) D*E
(2) G*H
(3) B*C
(4) 1*F
(5) 3+4
(6) 5+2

另请注意,如果BC等需要自行评估,那么这些评估也不会有任何相对排序。

答案 2 :(得分:-1)

  

我的想法是创建一个链接列表,我将检查我的+和*,   如果正在计算的对象(例如t2 * F)是临时的,   然后我可以删除它们/插入适当的。

鸵鸟政策。
这绝对没有意义,只有其他问题。很棒的时候。

编译器可以为您处理所有事情,您可以放心地依赖它。 C ++不是汇编程序级别。只返回临时的基于堆栈的对象(没有指针或任何东西)。计算的中间结果将自行清理。

Matrix operator+(const Matrix&) {...}  
Matrix operator*(const Matrix&) {...}  

并且每个这样的函数都有一个临时对象insde to calcualte,然后返回 这就是你需要的一切。