【问题标题】:incorrect output on vector assignment? [duplicate]矢量分配的输出不正确? [复制]
【发布时间】:2015-12-07 10:25:13
【问题描述】:

以下代码 sn-p 来自 Herb Sutter 的博客here

g++ 输出10。 MSVC 也输出10。不同编译器的输出可能不同。

我不明白变量i 是如何递增的。 谁能解释一下为什么输出是1010 的输出真的正确吗?

#include <iostream>
#include <vector>
#include <string>

int main()
{    
    std::vector<int> v = { 0, 0 };
    int i = 0;
    v[i++] = i++;
    std::cout << v[0] << v[1] << std::endl;
}

【问题讨论】:

    标签: c++11 vector order-of-execution


    【解决方案1】:

    已编辑

    我们将不讨论未定义的行为,只关注您的程序如何到达指定的输出。

    首先,让我们陈述一个事实:

    • i++ 将增加 i 的值,但返回 i 在增加之前持有的原始值。

    来自What is the difference between ++i and i++?

    现在,一行

    v[i++] = i++;
    

    在您的情况下,按“LHS”->“RHS”-> 分配的顺序评估:

    • LHS,v[i++]:i 递增到 1,i++ 返回 0 到 v[i++]。
    • RHS,i++:i 现在的值为 1,但递增到 2,但 RHS 的 i++ 返回 1。
    • 赋值:从上面看,赋值结果为:v[0] = 1(之后 i 的值为 2)。

    因此,打印 v[0] 和 v[1] 将分别评估为 1(更新值)和 0(初始化)。

    【讨论】:

    • 非常好的方法来解释具体情况下发生了什么,我恢复了我的 dv!竖起大拇指。
    • 谢谢!我希望您的答案的两个反对者也会在您编辑后重新考虑,我认为这也是一个相关的答案。
    • 好吧,他们一开始就 dv 是对的,实际上我并不清楚问了什么!
    【解决方案2】:

    这是执行顺序问题,由于c++11未定义:

    5.17 赋值和复合赋值运算符

    赋值运算符 (=) 和复合赋值运算符 所有组从右到左。都需要一个可修改的左值作为左值 操作数并返回一个引用左操作数的左值。结果 如果左操作数是位域,则在所有情况下都是位域。 在 在所有情况下,赋值都是在 的值计算之后排序的 左右操作数,以及之前的值计算 赋值表达式.

    简单地说,左参数的修改是在值计算之后排序的,而不是计算的副作用,双方以及返回对象的引用之前。

    所以要采取的行动是

    A.计算左侧(表达式 i++ = 0 的返回值)

    B.返回对对象的引用(返回对表达式 v[i++] 的对象的引用)

    C.计算左侧的副作用,即 i-> 1

    D.计算右侧的副作用,即 i-> 2

    从上面的规则可以看出,订单是否为 ABCD 并不清楚 或者如果它应该是 ACBD ,因为副作用计算的顺序没有定义,它应该首先发生在左侧还是首先发生在右侧。

    【讨论】:

    • 只是 dv 但没有理由...可能是策略?!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多