단일요소를 단위로 동작하는 멤버함수보다 요소의 범위를 단위로 동작하는 멤버함수가 더 낫다.

두개의 백터 v1과 v2가 있다고 할때, v1의 내용을 v2의 뒤쪽 반과 같이 하는 가장 간단한 방법은





v1.assign(v2.begin()+v2.size()/2, v.end());

이다.
물론 루프를 사용할수도 있으며 copy 알고리즘과 back_insert 삽입연산자를 사용할수도 있다. 하지만 가능하다면 이경우는 vector에서 제공하는 멤버함수를 사용하는것이 좋다.

  • 범위멤버함수를 사용한 코드가 대개 짧다.
  • 범위멤버함수는 훨씬 명확하고 간결한 의미를 전달한다.
이다.
다른 예로 int 배열을 vector의 앞쪽에 복사할 경우
int data[numValues];
vector<int> v;

v.insert(v.begin(), data, data + numValues);
의 코드를 사용하게 되는데 이것을 copy 알고리즘을 이용해서 구현하면
copy(data, data + numValues, inserter(v, v.begin()));
같은 코드로 구성이 된다. 하지만 copy와 삽입연산자를 사용할 경우

  1. numValues 번에 해당하는 insert 함수의 호출하는 비용
  2. 앞쪽에다가 삽입함으로써 insert 호출시마다 vector를 뒤로 밀어버리는 비용
  3. 삽입시 컨테이너가 모자를 경우 생기는 메모리 할당 비용
같은 비용이 추가로 부담되게 된다. 왜냐하며 copy는 내부적으로 루프를 사용하는 것과 비슷한 방식으로 구현되어 vector의 insert를 여러번 호출하는것이나 마찬가지 이기 때문이다. 하지만 vector의 범위멤버인 insert를 호출함으로써 한번의 호출시 작업해야하는 범위를 파악하여 메모리 할당문제를 해결하고 순차적으로 각값을 넣음으로써 위의 세가지 비용문제를 해결할수 있다.

이런 문제는 vector 보다는 적지만 list 에서도 마찬가지 이다. list에 insert 를 호출시 삽입되는 위치의 앞과 뒤에 있는 노드의 서로를 연결시키는 포인터값을 수정해야 하며 이것 역시 추가적인 비용이 들어간다. 범위 insert를 호출한다면 위의 비용은 한번으로 줄어들 것이다.





정리

  • 범위 생성
    istream_iterator, istreambuf_interator 를 사용할 경우에는 주의
  • 범위 삽입 : 대부분의 컨테이너는 insert류의 함수를 제공한다. (연관컨테이너는 위치지정을 내부에서 비교함수를 따로 사용하기 때문에 위치지정은 없다.) push_back, push_front 나 back_insert, front_insert를 사용하는 루프나 copy 알고리즘이 있다면 insert 범위 멤버함수로 변경가능하다.
  • 범위 삭제 : erase 함수를 이영해서 삭제
  • 범위 대입 : 표준연속컨테이너에서 assign을 제공

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다