2010-08-10 3 views
1

다음 프로그램을 고려하십시오. 이 함수는 int에 대한 포인터 집합을 만들고 지시 된 정수의 값으로 집합을 정렬하는 사용자 정의 indrect_less 비교자를 사용합니다. 이 작업이 끝나면 필자는 지적 된 정수 중 하나의 값을 변경합니다. 그런 다음 집합의 순서가 더 이상 정렬되지 않는 것을 볼 수 있습니다 (집합이 변경된 것을 모르기 때문에).간접 참조를 통한 포인터 집합 무효화

합니다 (C++ 0X, 내가 VS2010에서 실행 해요 루프 신경 쓰지 마)

#include <iostream> 
#include <set> 
using namespace std; 

struct indirect_less { 
    bool operator()(int* l, int* r) const 
    { 
     return *l < *r; 
    } 
}; 

int main() 
{ 
    set<int*, indirect_less> myset; 

    int* a = new int(5); 
    int* b = new int(6); 
    int* c = new int(7); 

    myset.insert(a); 
    myset.insert(b); 
    myset.insert(c); 

    cout << "Set contains: "; 
    // (outputs: 5 6 7) 

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i) 
    { 
     cout << **i << " "; 
    } 

    cout << endl << "Modifying *a" << endl; 
    *a = 9;   // point of interest 
    cout << "Set contains: "; 
    // (outputs: 9 6 7 - unsorted order) 

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i) 
    { 
     cout << **i << " "; 
    } 

    cout << endl; 

    cin.get(); 

    return 0; 
} 

1) 내가 정의되지 않은 동작을 호출하고 있습니까 그 권리? 라인 *a = 9; 이후에 myset의 전체 상태가 유효하지 않습니까?

2) 이것을 수행하여 a을 다시 삽입하는 올바른 방법이 있습니까?

3) 어떤 식 으로든, *a = 9;이 실행되면, 잘 정의 된 동작으로 정렬 된 순서로 집합의 균형을 다시 잡으십시오?

+1

예, 예, 아니오로갑니다. –

+0

해당 행 다음에 어떤 동작이 정의되어 있습니까? 예를 들어, 정의되지 않은 순서로 세트를 반복해서 반복 할 수 있습니까? – AshleysBrain

+0

정의되지 않은 방법으로 작동하지 않습니다. 정의되지 않은 동작을 호출하면 모든 베팅이 해제됩니다. 프로그램은 계속해서 작동하는 것을 포함하여 모든 작업을 수행 할 수 있습니다. 그럴 때까지. 일반적으로 중요한 코드를 데모 할 때 사용합니다. – KeithB

답변

2

예, std::set은 요소를 변경할 수 없다고 가정합니다. possible입니다. 위험한 경우 각 변경 후에 직접 주문하십시오. 그래도 나는 추천하지 않을 것이다 : 다른 컬렉션 유형을 사용하라.

1

1) 예, set은 요소의 수정을 허용하지 않습니다.

2) 이전 값을 삭제하고 새 값을 삽입하는 것 외에 이전 세트를 새로 생성 된 값으로 바꿀 수도 있습니다.

3) 아니오

1

1) 나는 행동이 정의되지 않은 것을 알고하지 않습니다. 이 예제의 또 다른 트위스트는 세트의 요소가 변경되지 않는다는 것입니다. 세트의 각 요소는 포인터입니다. '* a = 9'줄을 실행하기 전후에 세트의 (포인터) 요소를 출력했으면 포인터 값이 할당 전후에 동일한 순서로 있음을 알았을 것입니다. 하나의 세트 요소가 가리키는 값. 이것은 세트의 후원 밖에서 발생했기 때문에 세트가 원하는 순서를 유지할 수있는 방법이 없습니다. 012) 집합의 요소를 정렬하는 데 사용되는 indirect_less(). 다시 포인터를 사용하여 각 요소의 포인터를 역 참조 포인터의 값으로 정렬한다는 점을 알아 두십시오. 그러나 이는 내가 위험하다고 생각합니다. .

인쇄물에서 "Set contains :"라는 전설에서 나는이 예제가 trives를 사용하여 정수 집합을 구성합니다. 그러나, 정의 된 세트, 즉, "세트"는 실제로는 정수가 아닌 정수에 대한 포인터로 구성된다. 나는 이것이 원하는 컬렉션과 실제 컬렉션 사이의 오정렬이 문제의 근본 원인이라고 믿는다.

3) 2)를 참조하십시오.

관련 문제