|
님의 소스를 보면 기존 TList 자료구조(ListString, TempStringList)를 그대로 두고
map에는 그 인덱스만 저장하는 구조로 되어있는데,
별로 좋은 방법은 아니군요.
기존 자료구조를 STL 기반으로 완전히 뜯어 고치시는 게 나을 겁니다.
그리고 이 경우는 별도의 키 값으로 자료를 접근하는게 아니고,
단지, 중복 없이 TTreeData를 저장하려는 경우이므로 map이 아니라 set을 사용해야 합니다.
(int, char, enum 만 저장할 수 있는 VCL의 Set과는 전혀 다른 겁니다.)
즉, 중복된 값은 절대 삽입되지 않습니다.
TTreeData 구조체 대신, 생성자와 멤버 변수(URL, id, Depth 등)를
수정하는 get/set 멤버 함수들을 완전히 정의한 클래스로 만드시고요,
set에 TTreeData 클래스 자체(클래스의 포인터가 아닙니다.)를
통째로 저장하는 편이 간단할 겁니다.
물론 set은 sequence associative container이므로
두 TTreeData의 순서(less-than 연산)를 정의하는 함수자(functor)도 정의해야 합니다.
template <typename Key,
typename Compare = less<Key>, // 이 함수 객체를 정의해야 합니다.
class Allocator = allocator<pair<const Key, T> > >
그리고 한 가지 더 코멘트하자면,
님의 소스에서 맵을 정의하실 때 다음과 같이 하셨는데요...
: std::map<AnsiString, int> freq;
map의 키 값의 타입으로는 Ansi C++ 라이브러리에서 less-than연산이 정의되어 있어야 합니다.
만약 AnsiString처럼 정의되지 않은 타입을 쓰려면 set에서와 같이 직접 정의를 해야 합니다.
이것은 map의 template parameter가 다음과 같이 정의되어 있기 때문입니다.
template <typename Key, typename T,
typename Compare = less<Key>, // 이 함수 객체를 정의해야 합니다.
class Allocator = allocator<pair<const Key, T> > >
차라리 AnsiString을 Ansi C++ 라이브러리의 string 타입으로 변환하는 것이 훨씬 편합니다.
물론 변환은 양쪽 다 c_str() 멤버 함수를 써서 char* 타입으로 하면 됩니다.
string str1 = "std_string";
AnsiString vclStr1 = "AnsiString";
string str2 = vclStr1.c_str();
AnsiString vclStr2 = str.c_str();
STL을 쓰실 때는 AnsiString 보다는 string을 쓰는 편이 여러모로 편합니다!
|