Programming Study/STL 썸네일형 리스트형 함수 어댑터(function adaptor) 지금까지 살펴본 제네릭 STL 알고리즘들 중 자신의 수행 방식을 조정하기 위해서 함수 객체를 인자로 사용하는 알고리즘이 꽤 많았다. 함수 객체와 반복자는 둘 다 알고리즘 어댑터로써의 역할을 수행한다. 반복자 어댑터가 제네릭 알고리즘에 사용할 수 있는 반복자들을 좀 더 다양하게 만들어 주듯이, 함수 어댑터(function adaptor)를 이용하면 더 다양한 함수 객체를 만들어낼 수 있다. 아무래도 함수 어댑터를 사용하는 것이 구조체나 클래스를 정의하여 새로운 함수 객체 타입을 직접 만드는 것보다는 훨씬 쉽다. STL에서는 세 가지 부류의 함수 어댑터 즉, 바인더(binder), 부정자(negator), 함수 포인터 어댑터(adaptor for pointers to functions)가 제공된다. 이 어댑.. 더보기 반복자 어댑터(iterator adaptor) 반복자 어댑터(iterator adaptor)는 반복자 컴포넌트의 인터페이스를 변경하기 위해 사용하는 STL 컴포넌트이다. STL에서 제공하는 반복자 어댑터에는 역 반복자 어댑터(reverse iterator adaptor) 밖에 없다. 양방향 반복자나 임의 접근 반복자에 이 어댑터를 적용하면, 순회 방향이 반대인 반복자를 얻을 수 있다. 이렇게 변환된 반복자의 인터페이스는 원래의 것과 동일하다. 역 반복자 어댑터는 템플릿 클래스로 정의되며, 이 때 템플릿 인자는 반복자의 타입을 사용한다. 역 반복자 어댑터를 직접 사용하는 경우는 드물다. 왜냐하면, 모든 STL 컨테이너들이 이미 두 개씩의 역 반복자 타입을 제공하고 있기 때문이다(어댑터를 이용하여 미리 정의해 둔 것이다). 하나는 뮤터블(mutable).. 더보기 컨테이너 어댑터(container adaptor) 어댑터는 다른 STL 컴포넌트의 인터페이스를 변경하고자 할 때 사용하는 STL 컴포넌트이다. 어댑터는 템플릿 클래스로 정의되며, 어댑터를 적용할 컴포넌트의 타입이 템플릿 인자로 사용된다. STL에서 제공하는 어댑터에는 컨테이너 어댑터(container adaptor), 반복자 어댑터(iterator adaptor), 함수 어댑터(function adaptor), 이상 세 가지가 있다. 인터페이스를 변경시켜주는 메커니즘이 과연 어떠한 장점을 지니고 있는지 알아보기 위해, 우선 스택이나 큐와 같은 기본적인 데이터 구조를 제공하는데 있어서 어떠한 문제점이 있는지 살펴보자. 스택(stack)은 vector, list, deque보다 더 간단한 컨테이너이고, 게다가 이 세 종류의 컨테이너에서는 스택에서 필요로 하.. 더보기 함수객체 대부분의 STL 제네릭 알고리즘에서는(그리고 일부 컨테이너 클래스에서는) 인자로 넘겨받은 함수 객체를 이용하여, 알고리즘의 작동 방식을 다양하게 변형 시킬 수 있다. 이는 반복자를 이용하여 알고리즘을 제어하는 것과는 약간 다른 것이다. 일반적으로, 0개 이상의 인자를 받아서 값을 얻어내거나 계산의 상태를 변경할 수 있는 것들은 모두 함수 객체(function object)라고 할 수 있다. 따라서, C++의 일반 함수도 함수 객체의 일종이며, 함수 호출 연산자 operator()를 오버로딩한 클래스(또는 구조체(struct))의 객체도 함수 객체라고 부를 수 있다. 다음과 같은 일반 함수 뿐만 아니라, int multfun(int x, int y) { return x *y; } 아래와 같이 정의된 mul.. 더보기 정렬 연관 컨테이너 시퀀스 컨테이너에서는 데이터 아이템의 상대적인 순서를 유지하기 위해서 데이터 아이템들을 선형으로 저장하지만, 정렬 연관 컨테이너에서는 이러한 상대적 순서가 없어지고, 대신에 아이템에 담긴 키(key) 값으로(아이템 자체가 키인 경우도 있다) 원하는 아이템을 빠른 시간 내에 찾아낼 수 있도록 되어 있다. 연관 검색을 구현하는 방법 중에서 가장 일반적인 방법은 키 값을 저장할 때는 전순서(total order)로 정렬해서 저장하고(예를 들어, 아이템이 숫자인 경우에는 숫자 크기 순으로, 아이템이 문자열인 경우에는 사전식 순으로), 검색할 때는 이항 검색 알고리즘을 사용하는 것이다. 또 한 가지 방법은 해쉬(hash)를 사용하는 것인데, 키 공간(key space)을 몇 개의 부분 집합으로 나눈 뒤에 각각의 .. 더보기 시컨스 컨테이너(Sequence Container) 각각의 STL 컨테이너 클래스들은 소프트웨어에서 가장 중요한 개념의 하나인 데이터 추상화(data abstraction) 또는 추상 데이터 타입(abstract data types)의 좋은 본보기들이다. 추상 데이터 타입에서는 객체들의 집합과 이들객체에 가해지는 연산들의 집합을 제공한다. 객체와 연산에는 객체의 표현 방식이나 연산의 구현 방식에 상관없이, 보통 일반적으로 정의되어 있는 추상적인 의미가 부여된다. 추상 데이터 타입은 자신의 표현 방식과 구현 방식을 외부로부터 숨김으로써(이는 C++의 클래스를 통해 지원된다), 프로그래머가 타입 내부의 특정 세부 사항에 의존하지 않고 코드를 작성할 수 있도록 한다. 이것은 결과적으로 소프트웨어를 사용하는 동안 지속적으로 발생하는 코드의 수정과 관리를 보다 수.. 더보기 제네릭 알고리즘 STL은 STL에 포함된 다양한 데이터 구조에 두루 적용할 수 있는 알고리즘을 다수 제공하고 있다. STL의 알고리즘은 모두 제네릭하다. 즉, 각각의 알고리즘은 단 한 개의 데이터 구조에만 적용할 수 있는 것이 아니라, 여러 가지 다양한 데이터 구조에 사용될 수 있다는 것이다. STL 제네릭 알고리즘들은 각 알고리즘의 의미에 따라, 대략 네 가지 부류로 분류할 수 있다. 1. 변경 불가 시퀀스 알고리즘(nonmutating sequence algorithm) 2. 변경 가능 시퀀스 알고리즘(mutating sequence algorithm) 3. 정렬 관련 알고리즘(sorting-related algorithm) 4. 범용 수치 알고리즘(generalized numeric algorithm) 1. STL.. 더보기 반복자(iterator)_2 7. 삽입 반복자(insert iterator) 삽입 반복자는 보통의 경우 "덮어쓰기 모드(overwrite mode)"로 동작하는 제네릭 알고리즘을 "삽입 모드(insert mode)"로 바꿔준다. 다시 말해서, 삽입 반복자의 경우, *i = ... 을 사용하면 i 자리에 위치한 객체를 덮어쓰는 것이 아니라 삽입을 하게 되며, 이는 컨테이너의 삽입 멤버 함수를 이용하여 이루어진다. 삽입 반복자는 길이를 모르는 데이터 시퀀스를 입력 스트림이나 컨테이너에서 다른 컨테이너로 옮길 때 매우 유용하다. STL은 다음 세 가지 종류의 삽입 반복자를 제공한다. 각각의 삽입 반복자는 Container 타입을 템플릿 인자로 사용한다. - back_insert_iterator : Container의 push_back 멤.. 더보기 반복자(iterator)_1 반복자는 포인터와 유사한 객체로서 STL 알고리즘이 컨테이너에 저장된 객체들의 시퀀스를 순회할 때 사용한다. 반복자는 컨테이너와 제네릭 알고리즘 사이를 이어주는 중간자로서, STL 설계에 있어서 매우 중심적인 역할을 담당하고 있다. 이러한 반복자 덕분에 데이터 구조의 저장방식에 관계없이 알고리즘을 구현할 수 있는 것이다. 그러나 효율성을 위해서는 모든 제네릭 알고리즘이 모든 컨테이너와 작동이 가능하도록 할 수는 없다(즉, 제네릭 알고리즘의 범용성이 제한된다). 그렇다면 주어진 제네릭 알고리즘과 컨테이너가 상호간에 작동이 가능한지는 어떻게 알 수 있는가? 이 물음에 답변하기 위해서는, 우선 STL 이면에 깔려 있는 핵심적인 기술 개념을 하나 알아둬야 할 필요가 있다. 그것은 반복자가 다음 다섯 가지의 부류.. 더보기 STL과 다른 라이브러리와의 차이점 STL 컴포넌트들에 관한 세부적인 설명에 들어가기에 앞서서, 우선 STL이 기존의 다른 C++ 라이브러리와 어떤 점에서 크게 차이가 나는지 살펴보고 넘어가도록 하자. 우선 첫 번째로, 기존의 C++라이브러리에는 상위 클래스가 동일한 클래스의 객체들만 컨테이너에 담을 수 있다는 제약 사항이 있기 때문에, 이들 라이브러리에서 제공하는 컨테이너들은 사용하기가 불편하다. 하지만 STL 컨테이너에서는 이러한 종류의 상속을 요구하지 않으며, 따라서 내장 타입을 포함한 어떠한 종류의 객체도 담을 수 있다. 두 번째로, 기존의 컨테이너 클래스 라이브러리에서는 알고리즘들이 모두 특정 클래스의 멤버 함수로 구현되어 있다. 예를 들어, 기존의 라이브러리에서 제공하는 리스트 클래스가 find라는 검색 알고리즘을 가지고 있다면.. 더보기 이전 1 2 다음