使用前缀或后缀增量(或减量)

时间:2014-03-23 13:15:52

标签: c++ operators

我发现这段代码是C ++书籍中使用逗号运算符的一个例子(C ++ Primer,第5版):

vector<int>::size_type cnt = ivec.size();
// assign values from size...1 to the elements in ivec
for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt)
    ivec[ix] = cnt;

我不认为这是一个恰当的例子,因为order of evalation和副作用在这里并不重要。逗号运算符只允许分离递增和递减表达式,这是逗号运算符的常见用法,但不是本书中本节的用意。 example显示更好的cppreference.com(请向下滚动到标题内置逗号运算符)。

我真正想到的是以下练习:

  

练习4.31 本节中的程序使用前缀增量和减量运算符。解释为什么我们使用前缀而不是   后缀。使用后缀需要进行哪些更改   版本?使用后缀运算符重写程序。

在这种情况下,没有特别的理由在postfix运算符上使用前缀。评估顺序并不重要。使用simple类型vector<int>::size_type类型的对象操作不应该在实践中使用前缀而不是后缀,因此它只是一个已知的约定,更喜欢使用前缀而不是后缀,表现事项很重要。

为了给你完整的背景,这里是书中的部分:

  

4.10逗号操作员
  逗号运算符采用两个操作数,它从左到右进行计算。像逻辑 AND 和   逻辑 OR 和条件运算符,逗号运算符   保证评估其操作数的顺序。

     

评估左侧表达式并将其结果删除。   逗号表达式的结果是其右手的值   表达。如果右手操作数为a,则结果为左值   左值。逗号运算符的一个常见用法是for循环:

vector<int>::size_type cnt = ivec.size();  
// assign values from size...1 to the elements in ivec  
for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt)  
    ivec[ix] = cnt;  
     

此循环递增 ix 并减少表达式中的 cnt   标题。每次旅行都会更改 ix cnt   循环。只要 ix 的测试成功,我们就会重置    next cnt 当前值的当前元素。

我是对的吗?或者我没有达到这个练习的目的?

1 个答案:

答案 0 :(得分:8)

你是正确的使用前缀或后缀增量运算符在这个例子中并不重要,但 C ++ Primer 也表示只在真正需要时才使用postfix版本作为最佳实践,我引用了§4.5中的这本书。增量和减量运算符

  

建议:仅在必要时使用后缀操作符

     

来自C背景的读者可能会对我们在我们编写的程序中使用前缀增量感到惊讶。原因很简单:前缀版本避免了不必要的工作。它递增值并返回递增的版本。后缀运算符必须存储原始值,以便它可以返回未递增的值作为其结果。如果我们不需要未增加的值,则不需要后缀运算符完成额外的工作。

     

对于int和指针,编译器可以优化掉这项额外的工作。对于更复杂的迭代器类型,这种额外的工作可能会更昂贵。通过习惯使用前缀版本,我们不必担心性能差异是否重要。而且 - 或许更重要的是 - 我们可以更直接地表达我们计划的意图。