"데브피아 - 윤용한 님 번역"
------------------------------------------------------------------------
STL (Standard Templete Library) part-11(final)
Yonghan, Yoon
yonghany@orgio.net
------------------------------------------------------------------------
THE WAITE GROUP's
Object-Oriented Programming in C++
Third Edition
Robert Lafore(Author)
SAMS(Publisher)
------------------------------------------------------------------------
드디어 STL 마지막 글을 끝냈습니다.^^v
그동안 저의 엉터리(?) 번역을 고통스럽게 읽어 주셔서 감사합니다.
내용중에 오타도 있을 것이고, 이상한 문구도 있을 것이라 생각이 듭니다.
이러한 사항들은 STL을 공부하면서 궁금한게 있다면 저에게 메일주시면
답변드리는 걸루 대신 하겠습니다.^^
* 참고로 글 마지막에 참고할만한 사이트 몇개와 추천할만한 책을 적어두었습니다.
6. Storing User-Defined Objects
이제까지 언급된 예제들은 기본타입으로 존재하는 오브젝트만 다루었지만 STL은
사용자가 작성한 오브젝트 클래스로도 작업할 수 있다. 이번 장에서는 사용자 정의
오브젝트에 대해서 다루어본다.
6.1 A Set of person Objects
이름, 성, 전화번호를 갖는 person 클래스로 시작해보자. 이 클래스를 set에 저장시켜
전화번호 데이터베이스를 만들것이다.
// setpers.cpp
// uses a multiset to hold person objects
#include <iostream>
#incldue <set>
#pragma warning (disable:4786) // for set (Microsoft only)
#include <string>
using namespace std;
class person
{
private:
string lastName;
string firstName;
long phoneNumber;
public:
person () : lastName ("blank"),
firstName ("blank"), phoneNumber (0)
{ }
person (string lana, string fina, long pho) :
lastName (lana), firstName (fina), phoneNumber (pho)
{ }
friend bool operator< (const person&, const person&);
friend bool operator== (const person&, const person&);
void display () const { // display person's data
cout << endl << lastName << ",\t" << firstName
<< "\t\tphone: " << phoneNumber;
}
};
bool operator< (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName)
return (p1.firstName < p2.firstName) ? true : false;
return (p1.lastName < p2.lastName) ? true : false;
}
bool operator== (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName &&
p1.firstName == p2.firstName
return (p1.firstName < p2.firstName) ? true : false;
}
//////////////////////////////////////////////////////////////////////////
int main ()
{
// person 오브젝트 생성
person pers1 ("Deauville", "William", 8435150);
person pers2 ("McDonald", "Stacey", 3327536);
person pers3 ("Bartoski", "Peter", 6946473);
person pers4 ("KuangThu", "Bruce", 4157300);
person pers5 ("Wellington", "Jhon", 9207400);
person pers6 ("McDonald", "Amanda", 8435150);
person pers7 ("Fredericks", "Roger", 7049982);
person pers8 ("McDonald", "Stacey", 7764987);
multiset < person, less<person> > persSet; // person들의 multiset
multiset < person, less<person> >::iterator iter; // iterator
// multiset에 person 오브젝트를 추가한다.
persSet.insert (pers1);
persSet.insert (pers2);
persSet.insert (pers3);
persSet.insert (pers4);
persSet.insert (pers5);
persSet.insert (pers6);
persSet.insert (pers7);
persSet.insert (pers8);
cout << "\nNumber of entries = " << persSet.size();
// multiset의 content를 출력한다.
iter = persSet.begin();
while (iter != persSet.end())
(*iter).display();
// lastName과 firstName을 입력받는다.
string searchLastName, searchFirstName;
cout << "\n\nEnter last name of person to search for: ";
cin >> searchLastName;
cout << "Enter first name: ";
cin >> searchFirstName;
// 입력받은 이름으로 searchPerson 오브젝트를 생성한다.
person searchPerson (searchLastName, searchLastName, 0);
// 해당 이름을 가진 사람이 몇명인가 세어본다.
int cntPersons = persSet.count (searchPerson);
cout << "Number of persons with this name = " << cntPersons;
// 해당 이름을 가진 사람들을 모두 출력한다.
iter = persSet.lowe_bound (searchPerson);
while ( iter != persSet.upper_bound (searchPerson) )
(*iter).display ();
cout << endl;
return 0;
}
person 클래스가 STL 콘테이너로 작동되기 위해서는 몇가지 공통으로 쓰이는 멤버함수가
필요하다. 바로 기본생성자, < 오퍼레이터, == 오퍼레이터들이 필요하다. 이 멤버함수들은
리스트 클래스와 여러 알고리즘에서 유용하게 사용된다. 또한 특수한 경우를 위해
필요한 멤버함수를 정의할 수도 있다. 오퍼레이터 < 와 == 는 const 인자이어야 하고
friend로 하는게 좋다 (멤버함수로 해도 상관은 없다).
오버로드된 < 오퍼레이터는 set에 저장될때 정렬방식을 나타낸다. 예제 setpers에서는
last name을 정렬하기위해 사용되었고, last name이 동일하면 first name으로 순서를 정하게
만들었다. 위 프로그램의 결과는 아래와 같다.
Number of entries = 8
Bartoski, Peter phone: 6946473
Deauville, William phone: 8435150
Fredericks, Roger phone: 7049982
KuangThu, Bruce phone: 4157300
McDonald, Amanda phone: 8435150
McDonald, Stacey phone: 3327536
McDonald, Stacey phone: 7764987
Wellington, Jhon phone: 9207400
Enter last name of person to search for: McDonald
Enter first name: Stacey
Number of persons with name = 2
McDonald, Stacey phone: 3327536
McDonald, Stacey phone: 7764987
6.2 A List of person Objects
위의 SETPERS 예제에서, set이나 multimap으로 주어진 이름을 검색하는 것은 매우 빠르다.
그렇지만, person 오브젝트를 빠르게 삽입하고 삭제하기를 고려한다면 list의 사용을
고려해야한다.
// listpers.cpp
// uses a list to hold person objects
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
using namespace std;
class person
{
private:
string lastName;
string firstName;
long phoneNumber;
public:
person () : lastName ("blank"),
firstName ("blank"), phoneNumber (0L)
{ }
person (string lana, string fina, long pho) :
lastName (lana), firstName (fina), phoneNumber (pho)
{ }
friend bool operator < (const person&, const person&);
friend bool operator == (const person&, const person&);
friend bool operator != (const person&, const person&);
friend bool operator > (const person&, const person&);
void display () const { // display person's data
cout << endl << lastName << ",\t" << firstName
<< "\t\tphone: " << phoneNumber;
}
long get_phone () const {
return phoneNumber;
}
};
bool operator < (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName)
return (p1.firstName < p2.firstName) ? true : false;
return (p1.lastName < p2.lastName) ? true : false;
}
bool operator == (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName &&
p1.firstName == p2.firstName)
return (p1.firstName < p2.firstName) ? true : false;
}
bool operator != (const person& p1, const person& p2)
{
return !(p1 == p2)
}
bool operator > (const person& p1, const person& p2)
{
return !(p1 < p2) && !(p1 == p2);
}
int main ()
{
list <person> persList; // list of person
list <person>::iterator iter1; // iterator to a list of persons
// put persons in list
persList.push_back (person("Deauville", "William", 8435150));
persList.push_back (person("McDonald", "Stacey", 3327536));
persList.push_back (person("Bartoski", "Peter", 6946473));
persList.push_back (person("KuangThu", "Bruce", 4157300));
persList.push_back (person("Wellington", "Jhon", 9207400));
persList.push_back (person("McDonald", "Amanda", 8435150));
persList.push_back (person("Fredericks", "Roger", 7049982));
persList.push_back (person("McDonald", "Stacey", 7764987));
cout << "\nNumber of entries = " << persList.size();
iter1 = persList.begin (); // display contents of list
while ( iter != persList.end() )
(*iter1++).display();
// find person or person with specified name (last and first)
string searchLastName, searchFirstName;
cout << "\n\nEnter last name of person to search for: ";
cin >> searchLastName;
cout << "Enter first name: ";
cin >> searchFirstName;
// make a person with that name
person searchPerson (searchLastName, searchFirstName, 0L);
// search for first match of names
iter1 = find (persList.begin(), persList.end()m searchPerson);
// find additional matches
if ( iter1 != persList.end() ) {
cout << "Person(s) with that name is(are)";
do {
(*iter1).display (); // display match
++iter1; // search again, one past match
iter1 = find (iter1, persList.end(), searchPerson);
} while (iter1 != persList.end());
}
else
cout << "There is no person with that name.";
// find person or persons with specified phone number
cout << "\n\nEnter phone number (format 12345678): ";
long sNumber; // get search number
cin << sNumber;
// iterate through list
bool found_one = false;
for (iter1=persList.egin(); iter1!=iter1.end(); iter1++) {
if (sNumber == (*iter).get_phone()) { // compare numbers
if (!found_one) {
cout << "Person(s) with that phone number is(are)";
found_one = true;
}
(*iter1).display();
}
}
if (!found_one)
cout << "There is no person with that phone number";
cout << endl;
return 0;
}
}
}
//////////////////////////////////////////////////////////////////////////
이름으로 검색할때:
위의 예제는 list를 사용하기때문에 lower_bound()/upper_bound() 멤버함수를
사용할 수가 없다. 대신에 검색을 하기위해 find() 알고리즘을 이용하여 list의
모든 멤버를 비교하게된다. 우선 최초검색을 하고, 발견되면 그 다음 위치부터
루프를 돌며 계속 비교를 하게 된다. 즉 find()를 두번 써야한다.
Phone Number로 검색할때:
find()는 검색하기위해 1차적 검색 특성(primary search characteristic)을 이용하기 때문에
이름으로 검색하는 것보다는 어렵다. 예제에서 전하번호를 찾기위해 brute force 기법을
사용하였다. 이 기법은 리스트 전체를 순회하면서 찾고자 하는 항목을 수동적으로
비교해나간다.
if ( sNumber == (*iter).get_phone() )
...
프로그램은 먼저 모든 엔트리를 출력하고나서 검색할 이름을 묻는다. 입력받은 이름을
찾아서 출력해주고, 다음과정으로 검색할 전화번호를 묻는다. 그리고 다시한번 검색을
하게된다. 결과는 다음과 같다.
Number of entries = 8
Deauville, William phone: 8435150
McDonald, Stacey phone: 3327536
Bartoski, Peter phone: 6946473
KuangThu, Bruce phone: 4157300
Wellington, Jhon phone: 9207400
McDonald, Amanda phone: 8435150
Fredericks, Roger phone: 7049982
McDonald, Stacey phone: 7764987
Enter last name of person to search for: wellington
Enter first name: Jhone
Person(s) with that name is(are)
Willington, Jhone phone: 920704
Enter phone number (format 1234567): 8435150
Person(s) with that number is(are)
Deauville, William phone: 8435150
McDonald, Amanda phone: 8435150
여기서 염두해두어야 할것은 리스트(list)에 클래스 오브젝트를 저장하기 위해서는
이 클래스 오브젝트가 반드시 ==, != >, < 이 4가지 오퍼레이터를 정의하고 있어야
된다는 것이다. 이유는 간단하다. 검색을 위해 비교가 수반되기 때문이다.
7. Function Objects
function object는 STL 전반에 걸쳐서 쓰인다. 한가지 중요한 것은 어떤 알고리즘의 인자로
바로 사용될 수 있다는 것이다. 함수객체는 알고리즘의 동작(operation)을 custermize할
수도 있다. 이미 앞에서 다루었던 예제 SORTEMP에서 미리 정의된 함수객체로서 greater<>()
라는 것을 이용하여 역순으로 정렬을 한 적이있다. 이번 섹션에서는 미리 정의된 몇몇의 또다른
함수객체들에 대해서 다루어보고 사용자 정의 함수객체에 대해서도 다루겠다.
함수객체가 class로 포장된 함수를 다시 호출하기 때문에 오브젝트처럼 보인다. 하지만
이 클래스(함수객체)는 데이터를 갖지 않고 오직 오버로드된 오퍼레이터 () 즉,
멤버함수만 갖고 있다. 종종 이 클래스는 템플릿화되어서 어떤 타입이던지 사용이 가능한 것도 있다.
7.1 Predefined Function Objects
STL에서 functional 헤더화일에 함수객체가 미리 정의 되어있다.(테이블 7.10 참조)
여기에 있는 함수객체들은 C++ 오퍼레이터와 같은 기능을 하는 것들이다.
테이블에서 T 는 타입이 정해지지 않아서 아무 클래스나 사용가능하다는 뜻이다.
변수 x와 y는 인자로 함수객체로 전달되는 class T로 선언된 오브젝트를 나타낸다.
Table 7.10 Predifined Function Object
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Function Object Return value
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
T = plus (T, T) x+y
─────────────────────────────────────
T = minus (T, T) x-y
─────────────────────────────────────
T = times (T, T) x*y
─────────────────────────────────────
T = divide (T, T) x/y
─────────────────────────────────────
T = modulus (T, T) x%y
─────────────────────────────────────
T = negative (T) -x
─────────────────────────────────────
bool = equal_to (T,T) x==y
─────────────────────────────────────
bool = not_equal_to (T,T) x!=y
─────────────────────────────────────
bool = greater (T,T) x>y
─────────────────────────────────────
bool = less (T, T) X<y
─────────────────────────────────────
bool = greater_equal(T,T) x>=y
─────────────────────────────────────
bool = less_equal(T,T) x<=y
─────────────────────────────────────
bool = logical_and (T,T) x && y
─────────────────────────────────────
bool = logical_or (T, T) x || y
─────────────────────────────────────
bool = logical_not (T) !x
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
여기에 나온 함수객체들은 산술 오퍼레이터, 비교, 논리 오퍼레이션들이다.
이제 예제로 함수객체로 간단하게 산술연산을 살펴보자. 예제에서 시간과 분을
멤버변수로 갖고, 비행기 도착과 출발시간을 표현하는 airtime이라는 클래스를 정의한다.
이 클래스를 가지고 plus<>() 함수객체를 어떻게 사용하는지를 기술한다.
// plusair.cpp
// uses accumulate () algorithm and plsu() function object
#include <iostream>
#include <list>
#include <numeric> // for accumulate ()
using namespace std;
//////////////////////////////////////////////////////////////////////////
class airtime
{
private:
int hours; // 0 to 23
int minutes; // 0 to 59
public:
// 기본 생성자
airtime() : hours(0), minutes(0)
{ }
// 2개의 인자를 가지는 생성자
aittime (int h, int m) : : hours(h), minutes(m)
{ }
// 화면출력
void display () const {
cout << hours << ':' << minutes << endl;
}
// 입력받기
void get () {
char dummy;
cout << "\nEnter airtime (format 12:59): ";
cin >> hours >> dummy >> minutes;
}
// + 오퍼레이터 오버로드
airtime operator + (const airtime rhs) const {
int temph = hours + rhs.hours;
int tempm = minutes + rhs.minutes;
if (tempm >= 60) {
temph++;
temp -= 60;
}
return airtime (temph, tempm);
}
// == 오퍼레이터 오버로드
airtime operator == (const airtime & rhs) const {
return (hours == rhs.hours) && (minutes == rhs.minutes);
}
// < 오퍼레이터 오버로드
airtime operator < (const airtime & rhs) const {
return (hours < rhs.hours) ||
(hours < rhs.hours) && (minutes < rhs.minutes);
}
// != 오퍼레이터 오버로드
airtime operator != (const airtime & rhs) const {
return !(*this==rhs);
}
// > 오퍼레이터 오버로드
airtime operator < (const airtime & rhs) const {
return !(*this < rhs);
}
};
int main ()
{
char answer;
airtime temp, sum;
list <airtime> airlist; // list of airtime
do {
temp.get(); // 사용자 입력을 받는다.
airlist.push_back( temp);
cout << "Enter another (y/n)? ";
cin >> answer;
} while (answer != 'n');
// 모든 airtime을 더한다.
sum = accumulate ( airlist.begin(), airlist.end(), airtime(0,0), plus<airtime>() );
cout << "\nsum = ";
sum.display ();
cout << endl;
return 0;
}
이 프로그램의 요점은 accumulate() 알고리즘이다. 이 알고리즘은 2가지 버전을 가지는데
3-인자 버전은 항상 값의 범위만 더하고(+오퍼레이터를 이용) 위에서 사용한
4-인자 버전은 테이블 7.10에서 표현한 것처럼 산술오퍼레이터가 있는 아무 클래스나 사용이
가능하다.
4-인자 버전의 accumulate()는 범위의 처음에서 끝까지 순회하면서 plus<>()함수객체를
통해 연산을 하게 된다.
예제를 간단하게 시뮬레이션 한결과:
Enter airtime (format 12:59) : 3:45
Enter another (y/n) ? y
Enter airtime (format 12:59) : 5:10
Enter another (y/n) ? y
Enter airtime (format 12:59) : 2:25
Enter another (y/n) ? y
Enter airtime (format 12:59) : 0:55
Enter another (y/n) ? n
sum = 12:15
accumulate () 알고리즘은 간편할뿐만 아니라 직접 콘테이너를 이터레이트해서 계산하는
것보다 깔끔하다. 또한 아주 복잡한 코드를 추가하지 않는 이상 효율적이다.
plus<> () 함수객체는 + 오퍼레이터가 필요하다. 이 오퍼레이터들은 plus<>() 함수객체가
const형을 필요로하므로 반드시 const형이어야 한다.
다른 산술 함수객체들도 이와 사용이 거의 같다고 보면 된다.
7.2 Writing Your Own Function Objects
만일 표준 함수객체가 자신이 필요로하는 기능이 없다면 직접 작성할 수도 있다.
다음 예제는 sort() 알고리즘이 요구되는 상황과 for_each()가 요구되는 상황을 나타낸다.
클래스에 < 오퍼레이터가 정의된 것을 정렬하기는 간단하다. 그렇지만 콘테이너가
오브젝트 자신을 가리키는 포인터를 포함하고 있다면 무슨일이 발생할까? 포인터를
저장하는 것은 효율성을 향상시키지만 포인터를 정렬해보면 엘리먼트들이 특정 값에 의해
정렬되는게 아니라 포인터 주소순으로 정렬된다는 사실을 알게 될것이다.
따라서 sort() 알고리즘으로 우리가 원하는 정렬을 위해서는 함수객체를 만들어줄 필요가 있다.
아래의 예제는 person object 포인터를 저장하는 벡터의 선언으로 시작된다.
그리고 정렬을 해보면 포인터 주소순으로 정렬이 된다. 이것은 우리가 원하는 것이 아니다.
그리고 이것은 절대 순서를 변경시키지도 않는다. 다음 동작으로 comparePersons()
함수객체를 이용하여 정렬을 하면 이름순으로 정확하게 정렬이 된다.
// sortptrs.cpp
// sorts person objects stored by pointer
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
class person
{
private:
string lastName;
string firstName;
long phoneNumber;
public:
person () : lastName ("blank"),
firstName ("blank"), phoneNumber (0L)
{ }
person (string lana, string fina, long pho) :
lastName (lana), firstName (fina), phoneNumber (pho)
{ }
friend bool operator < (const person&, const person&);
friend bool operator == (const person&, const person&);
void display () const { // display person's data
cout << endl << lastName << ",\t" << firstName
<< "\t\tphone: " << phoneNumber;
}
long get_phone () const {
return phoneNumber;
}
};
bool operator < (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName)
return (p1.firstName < p2.firstName) ? true : false;
return (p1.lastName < p2.lastName) ? true : false;
}
bool operator == (const person& p1, const person& p2)
{
if (p1.lastName == p2.lastName &&
p1.firstName == p2.firstName)
return (p1.firstName < p2.firstName) ? true : false;
}
//------------------------------------------------------------------------------
// function object to compare persons using pointers
class comparePersons
{
public:
bool operator () (const person* ptrP1,
const person* ptrP2) const {
return *ptrP1 < *ptrP2;
}
};
//------------------------------------------------------------------------------
// function object to display a person using a pointer
class displayPerson
{
public:
void operator () (const person* ptrP) const {
ptrP->display ();
}
};
////////////////////////////////////////////////////////////////////////////////
int main ()
{
vector <person*> vectPtrsPers; // a vector of ptrs to persons
person *ptrP1 = new person ("KuanThu", "Bruce", 4157300);
person *ptrP2 = new person ("Deauville", "Whilliam", 8435150);
person *ptrP3 = new person ("Wellington", "John", 9207404);
person *ptrP4 = new person ("Bartoski", "Peter", 6946473);
person *ptrP5 = new person ("Frederick", "Roger", 7049982);
person *ptrP6 = new person ("McDonald", "Stacy", 7764987);
vectPtrsPers.push_back (ptrP1);
vectPtrsPers.push_back (ptrP2);
vectPtrsPers.push_back (ptrP3);
vectPtrsPers.push_back (ptrP4);
vectPtrsPers.push_back (ptrP5);
vectPtrsPers.push_back (ptrP6);
for_each ( vectPtrsPers.begin(),
vectPtrsPers.end(), displayPerson() );
sort ( vectPtrsPers.begin(), vectPtrsPers.end() );
cout << "\n\nSorted pointers";
for_each ( vectPtrsPers.begin(),
vectPtrsPers.end(), displayPerson() );
sort ( vectPtrsPers.begin(), vectPtrsPers.end(), comparePersons() );
cout << "\n\nSorted pointers";
for_each ( vectPtrsPers.begin(),
vectPtrsPers.end(), displayPerson() );
while ( !vectPtrsPers.empty() ) {
delete vectPtrsPers.back();
vectPtrsPers.pop_back();
}
cout << endl;
return 0;
}
결과:
KuanThu, Bruce phone:4157300
Deauville, Whilliam phone:8435150
Wellington, John phone:9207404
Bartoski, Peter phone:6946473
Frederick, Roger phone:7049982
McDonald, Stacy phone:7764987
Sorted pointers
KuanThu, Bruce phone:4157300
Deauville, Whilliam phone:8435150
Wellington, John phone:9207404
Bartoski, Peter phone:6946473
Frederick, Roger phone:7049982
McDonald, Stacy phone:7764987
Sorted persons
Bartoski, Peter phone:6946473
Deauville, Whilliam phone:8435150
Frederick, Roger phone:7049982
KuanThu, Bruce phone:4157300
McDonald, Stacy phone:7764987
Wellington, John phone:9207404
첫번째 정렬 결과는 포인터 순서대로 이루어졌고 두번째 정렬결과는 이름으로 정확하게
정렬이 되었다.
--------------------------------------------------------------------------------
* 유용한 STL 사이트들
제가 알고 있는 STL사이트 들입니다.
[외국]
URL: http://www.lsc.nd.edu/research/mtl/
설명: Silicon Graphics Computer Systems, Inc.
실리콘 그래픽스(SGI) 사에서 관리하고 있는 사이트로 STL에 관한 매우
방대한 자료를 제공하고 있습니다. 여기서 다루고 있는 STL은 SGI에서
자체적으로 구현한 STL이지만, 표준과 그다지 많은 차이는 없습니다.
STL에 관한 자료가 부족했던 때부터 사람들이 가장 많이 참조했던
사이트였다고 생각됩니다. Tutorial이 아니고, 필요한 것을 찾아보는
manual의 성격을 띄고 있어, 초보자들에겐 좀 부담스러울 것입니다.
(밑에 sjjung가 작성한 소개글)
URL: http://www.sgi.com/Technology/STL/
설명: The Matrix Template Library (MTL)
STL을 이용하여 행렬(Matrix)을 구현한 것입니다(소스 및 샘플 다운가능)
소개글에는 high-performance라는데...
[국내]
URL: http://wwwoopsla.snu.ac.kr/~sjjung/stl/
설명: 서울대학교 OOPSLA lab의 sjjung개인 홈 (한글로 된 사이트!!! ^_^ )
레퍼런스 사이트에 대해서도 정리를 잘해놓은 곳입니다.
* 추천 할만한 STL Book
제목: Thinking in C++, Second Edition (Volumes 1 & 2)
다운받을 수 있는 곳: http://www.bruceeckel.com/
특징:
우선은 이 책이 온라인버전은 무료(Free electronic book)라는 것입니다.
1판은 한권에 STL에 약간 소개되는 정도였지만 2판이 나오면서 2권으로 분권이 되고
볼륨2에서 템플릿 및 STL에 대해서 집중적으로 다루고 있더군요.
또한 여기서 다루는 예제들도 바로 실무에 적용가능할 만한 것들을 다루고 있어
공부도 되고 유용한 라이브러리도 얻을 수 있는 책입니다.
* 제가 올린 STL에 관한 글은 처음에 언급하고 매번 출처를 표시했지만 다시한번
적습니다.
THE WAITE GROUP's Object-Oriented Programming in C++ Third Edition
Robert Lafore(Author) SAMS(Publisher)
Chapter 15 THE STANDARD TEMPLATE LIBRARY
이 책은 단지 STL만을 공부하기 위해 구입할 만한 책은 아닙니다 (제가 여기에 번역을
올렸으니 더더군다나 살필요가 없겠죠^^)
이 글과 관련있는 글을 자동검색한 결과입니다 [?]