实际使用C++前缀增量运算符返回左值的事实

Alw*_*ing 8 c++ c++11

我刚刚了解到C++中前缀增量运算符的结果是左值.有可能这种行为有助于程序员更有效,但我想不到任何.前缀增量运算符的这种行为有哪些惯用的用法?

Jam*_*nze 6

前缀++返回左值的原因是正交性; 我没有看到任何使用它不符合混淆的条件.但问题是:什么规则适用于使表达式成为左值.在C中,基本规则是修改其中一个操作数的表达式不是左值,但是许多人想要支持以下内容:

T&
someFunction( T& lhs, T const& rhs )
{
    //  ...
    return lhs = rhs;
}
Run Code Online (Sandbox Code Playgroud)

这适用于用户定义的类型(因为operator=它将是一个成员函数),并且一些成员也希望为内置类型支持它.因此,基本规则变为:如果运算符需要一个左值操作数,它修改了它,并且运算符的结果是更改的操作数,那么它就是一个左值.(因此,虽然前缀++是左值,但后缀不是,因为表达式的结果不是更改的操作数.)

就个人而言,我不确定我是否同意.用以下方法替换上面的内容没有问题:

T&
someFunction( T& lhs, T const& rhs )
{
    //  ...
    lhs = rhs;
    return lhs;
}
Run Code Online (Sandbox Code Playgroud)

这就是我在自己的代码中编写的方式.但是鉴于第一个例子对于用户定义的类型是合法的(operator=返回a T&),并且许多委员会成员都喜欢它,将它扩展到内置类型似乎是合乎逻辑的,并且得到的规则是连贯的,甚至是如果没有人真正有机会使用前缀的结果++作为左值.

编辑:

只是为了说清楚:我在其中一次会议上(当我们定义C++ 98时)问了这个问题,这就是我得到的回复(如果我没记错的话,Andy Koenig,最早和Stroustrup一起工作) C++的实现).这也是使用operator=return a T&而不是a 的默认实现的理由T const&.


var*_*run 0

i=9;
j=10;
k = ((i)>(j))?(j):(++i);
Run Code Online (Sandbox Code Playgroud)

在上面的情况下,我们使用了前缀增量运算符,因为您可以 c 我们首先检查 i>j 在这种情况下为 false,然后我们将值 ++i 分配给 k,这将给我们 k=1。在一个语句中,我们使用了 i 两次,但一次值为 9,另一次值为 10。如果您尝试在没有前缀增量运算符的情况下实现此目的,我们将不得不使用另一个临时变量来存储 i 的值,然后增加 i 以分配给 k。不使用前缀运算符

  i=9;
 j=10;
Temp=i;
 i=i+1;
k = ((Temp)>(j))?(j):(i);
Run Code Online (Sandbox Code Playgroud)

尽管如此,如果我们到达 temp 大于 j 的条件,那么即使我们不使用 i 的值,i 的值也会增加。使用前缀运算符 tje 仅当 i 小于 j 时 i 的值才会递增。