在尝试确保两个变量的升序时,我在Visual Studio 2012 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
有没有什么好的解释,只是为了确保不再陷入类似陷阱?
答案 0 :(得分: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
我认为你的一些困惑来自于思考(或希望)任务会同时发生,但事实并非如此。分配tuple
或pair
时,子对象按从左到右的顺序分配。
答案 1 :(得分:3)
问题是std::minmax()
接受两个引用并返回一对引用。特别是,在您的情况下,它将返回一对,其中第一个元素是对x2
的引用,第二个元素是对x1
的引用。
另一方面,在作业的左侧,您有:
std::tie(x1, x2)
其中也创建了一对引用(确实,实际上是两个引用的元组,但这并不重要),但这次该对的第一个元素是对x1
的引用,而第二个元素是对x2
的引用。
然后,您将std::minmax()
返回的对分配给std::tie
返回的对,这意味着为x1
分配了x2
的值(1
1}}); 之后的,x2
被分配了x1
的新值(再一次,那是因为std::minmax()
返回了一对引用,所以该对的第二个元素&#34;看到&#34;赋值给x1
)的副作用,现在是1
。
这应该解释输出。