在C ++中,A + = B优于A = A + B,同样地,++ A是A ++?
我理解" ++ A" preincrement保证至少与A ++ A"后置。这在许多地方都有讨论,包括here和here。同样,A + = B预计至少与A = A + B一样快,为here。
我在看这个++:
//From https://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/
T T::operator++(int)() {
auto old = *this; // remember our original value
++*this; // always implement postincr in terms of preincr
return old; // return our original value
}
我的理由是,在最坏的情况下(可能来自复杂的对象类型)A = A + B必须检索并存储A并在将其保存回原始A位置之前添加B,而A + = B将需要B并直接将其添加到A.我的推理是否正确?
预计基本类型在编译时重新排列为相同,并且这实际上仅适用于需要运算符重载的复杂对象。
这是否一般扩展到大多数命令式语言?
答案 0 :(得分:6)
我想说的原因并不完全相同。我更喜欢A += B
超过A = A + B
的主要原因是简洁。 A += B
明确指出您要将B添加到A.如果A
是更复杂的表达式,则尤其如此:
node_capacities[std::make_pair(node1,node2)] += edge.capacity;
我从未发现A += B
的效果要比A = A + B
差。
答案 1 :(得分:4)
要记住的重要一点是C ++有运算符重载,这意味着te +=
运算符可能意味着与您期望的完全不同。
+=
运算符仅作为添加并分配给,如果“目标”类没有为其定义+=
运算符。运算符重载也意味着,例如x++
可能意味着不同的东西,具体取决于x
的类实例为运算符重载定义的内容。
答案 2 :(得分:3)
您应该更喜欢A += B;
。
如果你曾经写过一个A = A + B;
比A += B;
更好的类型,那么你应该改变operator+=
的实现,使其与A = A + B;
完全相同。
然而,反过来一般不能做;您通常无法以任何合理的方式修改operator+
,以使A = A + B;
与A += B;
完全相同。
因此,如果A += B;
和A = A + B;
之间存在差异,您应该期望A += B;
成为更好的选择。
答案 3 :(得分:1)
在大多数情况下,A + = B是优选的。正如您所指出的,A = A + B与A + = B的寄存器负载会更多。同样有趣的是阅读SSA。这用于编译器优化,可能有助于理解如何处理这种情况。正如您所说,由于编译器,大多数这些注意事项都是从程序员手中取出的,但是要注意这些事情是很好的。
在复杂对象中考虑的另一个考虑因素是调用getter可能产生的副作用,以及调用此类getter两次的余量。 (想想,A.get()= A.get()+ B.get())。然而,这应该是相对罕见的,因为在大多数情况下吸气剂不应该有副作用。
答案 4 :(得分:-2)
事实上,在C ++中你应该避免使用后缀运算符:
仅仅因为后缀解决方案将使用的值然后增加其值,这可能会有些危险,或者至少会降低某些性能。
您可以查看here以获取更多信息。