2012-06-07 2 views
1

나는 (그렇게 추한 보이는 이유는 묻지 마세요) 같은 C++ 코드를 가지고있다 - 당신이 생각해야 할 그 때문에 코드의 자세한 부분은 정말 의미)이 있습니다STL 세트의 삽입 메소드가 전달 된 객체의 값을 복사합니까?

IntSet temp; 
SuperSet superSet; 
for (uint i = 0; i < noItems; i++) { 
     temp.insert(i); 
     superSet.insert(temp); 
     temp.clear(); 
} 

를이 noItems 개의 정수 집합 (각각 하나의 정수 값을 포함하는 IntSet)을 준비하고 다른 집합 (SuperSet)에 삽입하기위한 것입니다. 다음과 같이 두 세트가 정의되어 의도 한대로

typedef unsigned int DataType; 
typedef std::set<DataType> IntSet; 
typedef std::set<IntSet> SuperSet; 

이 나를 위해,이 코드가 작동하지해야하기 때문에 단지 삽입 후 나는 temp을 삭제하고있어, 나는 insert는 참조로 점점 것을 발견 tempsuperSet에 인수 : 코드의 결과는 위의 제시된 pair<iterator,bool> insert (const value_type& x); (http://www.cplusplus.com/reference/stl/set/insert/는)

그래서, 나는 SuperSet 만 포함 IntSet 년대를 삭제 받아야합니다. 하지만 "불행히도"이 코드는 작동합니다 - 모든 IntSet은 적절한 값으로 채워져 있습니다 ... 그래서 제 질문은 - STL 세트의 삽입 방법은 실제로 본체에서 무엇을합니까? 그것은 단순히 참조로 전달 된 개체를 복사합니까? 그리고 객체 나 원시 타입을 넘기는 것 사이의이 메소드의 동작의 차이점은 무엇입니까?

답장을 보내 주셔서 감사합니다.

+2

"* 단순히 전달 된 개체를 참조로 복사합니까? *"예. "* 객체 또는 기본 유형을 전달할 때이 메소드의 동작이 다른 점은 무엇입니까? *"오버 헤드가 적습니다. – ildjarn

답변

1

insert()은 인수를 전달할 때 복사를 피하기 위해 참조 인수를 취합니다. 컬렉션에 항목을 저장할 때 복사본을 만듭니다. 이것이 clear()이이 경우에 작동 할 수있는 이유입니다. 또한,이 두 경우 모두 사실입니다, 그래서 당신은 temp을 "재사용"경우에도 유일한 방법은 새로운 요소를 확인하는 것입니다 삽입 할 수 있도록 값으로 SuperSet 저장 IntSet에 대한 superSet

+0

고마워, 그게 내가 알고 싶었던거야! – Maciek

0

귀하의 선언에 별도의 복사본이있을 것 사본. 사본은 원본으로 변경되기 때문에 IntSet 사본에 반영되지 않습니다.

이것은 특히 tempsuperSet으로 전달하는 방법에 적용되지만 C++ 11에서는 사용량이 비효율적입니다. 임시 변수로 사용할 로컬 변수를 선언하면 복사본을 강제로 이동 의미를 사용하지 못하게됩니다.

SuperSet superSet; 

for (DataType i = 0; i < noItems; i++) 
{ 
    superSet.insert(IntSet(&i, &i + 1)); 
} 

로 할인 최적화 컴파일러는 임시 IntSet을 만들고 하나의 요소로 초기화됩니다. 컴파일러는 이것이 임시라는 것을 알고 있기 때문에 이동 생성자를 사용하여 값을 삽입 할 수 있습니다. 이렇게하면 IntSet의 얕은 복사본이 전달되고 값이 기본 상태 (예 : nullptr에 대한 포인터)로 재설정되어 이 이동이됩니다.

관련 문제