2013-06-29 1 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 2했다 x1의 값을 할당됩니다, 그리고 1입니다 x2의 값을 할당됩니다, 명세서가 함께 발생하지만, 당신이 모든 인라인한다면 지금 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을 할당하면 하위 오브젝트가 왼쪽에서 오른쪽으로 순서대로 지정됩니다.

3

문제는 std::minmax()참조를 받아참조 한 쌍을 반환한다는 것입니다. 특히 첫 번째 요소는 x2에 대한 참조이고 두 번째 요소는 x1에 대한 참조 인 쌍을 반환합니다. 할당의 왼쪽에서

, 다른 한편으로는, 당신은 : 또한 참조의 한 쌍을 생성

std::tie(x1, x2) 

을 (좋아하는 실제로 두 개의 참조의 튜플,하지만 그건 중요하지 않습니다), 이번에는 쌍의 첫 번째 요소는 x1에 대한 참조이고 두 번째 요소는 x2에 대한 참조입니다.

그런 다음이 x1x2의 값 (1 임) 제 지정된 도착을 의미 std::tie 의해 반환 된 쌍에 의해 반환 std::minmax() 쌍 할당; x2는 (다시 std::minmax()는 참조 된 한 쌍의 리턴하기 때문에, 즉, 그래서 그 쌍의 두 번째 요소 x1에 할당 부작용을 "인식") x1새로운 값이 할당 도착하는 지금은 1입니다.

출력 내용을 설명해야합니다.