2013-06-29 25 views
6

虽然试图确保两个变量的升序,我遇到奇怪的异常在Visual Studio中,可以通过下面的代码片段来说明2012 C++编译器C++分配副作用

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 

有什么好的解释,只是为了确保不会再陷入类似的陷阱吗?

回答

4

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时,将按从左到右的顺序分配子对象。

3

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

这项任务的左侧,在另一方面,你必须:

std::tie(x1, x2) 

这也带来了对引用的(好吧,一个元组实际上是两个引用,但是,这并不重要),但这次该对的第一个元素是对x1的引用,而第二个元素是对x2的引用。

然后,通过分配回std::minmax()std::tie返回的一对,这意味着x1被分配的x2的值(这是1)的第一对; 后,x2被分配的x1值(再次,这是因为std::minmax()返回一对引用,使对的第二个元素“看到”分配的副作用:x1),其现在是1

这应该解释输出。