Mar*_*aux 2 c++ operator-overloading associativity operator-keyword
在完成学校作业时,我们不得不对操作员重载和模板做些什么.一切都很酷.我写:
template<class T>
class Multiplication : public Expression<T>
{
private:
typename std::shared_ptr<Expression<T> > l, r;
public:
Multiplication(typename std::shared_ptr<Expression<T> > l, typename std::shared_ptr<Expression<T> > r) : l(l), r(r) {};
virtual ~Multiplication() {};
T evaluate() const
{
std::cout << "*";
T ml = l->evaluate();
T mr = r->evaluate();
return ml * mr;
};
};
Run Code Online (Sandbox Code Playgroud)
然后一位朋友问我为什么他的代码以"错误"的顺序产生输出.他有类似的东西
T evaluate() const
{
std::cout << "*";
return l->evaluate() * r->evaluate();
};
Run Code Online (Sandbox Code Playgroud)
r->evaluate()之前打印调试信息的代码l->evaluate().我也在我的机器上进行了测试,只需将这三条线改为单线.
所以,我想,那么*应该是从右到左的联想.但在互联网上,他们说这是从左到右.有一些额外的规则吗?使用模板时可能有些特别之处?或者这是VS2012中的错误?
当我们说*从左到右的关联性时,我们的意思是表达式a*b*c*d将始终评估为(((a*b)*c)*d).而已.在您的示例中,您只有一个operator*,因此没有任何关联.
您遇到的是操作数的评估顺序.你在打电话:
operator*(l->evaluate(), r->evaluate());
Run Code Online (Sandbox Code Playgroud)
两个表达式都需要在调用之前进行评估operator*,但是C++标准未明确指定它们的评估顺序.在你的情况下,r->evaluate()首先得到评估 - 但这与关联性无关operator*.
请注意,即使您有a->evaluate() * b->evaluate() * c->evaluate(),也会将其解析为:
operator*(operator*(a->evaluate(), b->evaluate()), c->evaluate())
Run Code Online (Sandbox Code Playgroud)
基于运算符关联性的规则 - 但即使在这种情况下,也没有规则可以防止c->evaluate()首先被调用.它很可能是!