【问题标题】:C++ assignment side-effectC++ 赋值副作用
【发布时间】:2013-06-29 13:08:55
【问题描述】:

在尝试确保两个变量的升序时,我在 Visual Studio 2012 C++ 编译器中遇到了奇怪的异常,可以通过以下代码 sn-p 说明

    double x1 = 2;
    double x2 = 1;
    std::tie(x1, x2) = std::minmax(x1, x2);
    std::cout << "x1 = " << x1 << ",   x2 = " << x2 << "\n";

人们会认为 x1 是 1 而 x2 是 2。但事实并非如此。而是

    //output:
    //x1 = 1,   x2 = 1

有什么好的解释,以免再次陷入类似的陷阱?

【问题讨论】:

    标签: c++ visual-studio-2012 tuples


    【解决方案1】:

    std::minmax 通过引用返回其参数。你的语句发生的情况是,首先x1 被分配x2 的值,即1。然后,x2 被分配x1 的值,它是2,但现在是1。

    如果你要内联所有内容,它可能看起来像这样:

    // using pointers because references can't be rebound
    double *less, *greater;
    
    if (x1 <= x2)
    {
        less = &x1;
        greater = &x2;
    }
    else
    {
        // in your case, this is the branch taken
        less = &x2;
        greater = &x1;
    }
    
    x1 = *less;       // less points to x2, so now both x1 and x2 = 1
    x2 = *greater;    // greater points to x1, and x1 = 1, so this assignment is redundant
    

    我认为您的部分困惑来自于认为(或希望)这些作业会同时发生,但事实并非如此。当您分配tuplepair 时,子对象按从左到右的顺序分配。

    【讨论】:

      【解决方案2】:

      问题在于std::minmax() 接受两个引用并返回一对引用。特别是,在您的情况下,它将返回一个对,其中第一个元素是对 x2 的引用,第二个元素是对 x1 的引用。

      另一方面,在作业的左侧,您有:

      std::tie(x1, x2)
      

      这也创建了一对引用(好吧,实际上是两个引用的元组,但这没关系),但这一次对的第一个元素是对x1的引用,而第二个元素是对x2 的引用。

      然后,你将std::minmax()返回的pair赋值给std::tie返回的pair,这意味着x1首先被赋值为x2(即1); 在那之后x2 被分配了x1值(再一次,这是因为std::minmax() 返回了一对引用,所以第二个元素对“看到”分配给x1) 的副作用,现在是1

      这应该解释输出。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-26
        • 1970-01-01
        • 1970-01-01
        • 2013-11-09
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 2021-03-16
        相关资源
        最近更新 更多