[완료] C++: 템플릿 함수로의 변환
글쓴이: dummytoguru / 작성시간: 금, 2007/03/30 - 9:56오후
Essential C++ 3.6절을 보다가 질문드립니다.
주어진 백터 중 특정한 값보다 작은 값만을 갖는 새로운 백터를 반환하는 함수인 less than()을 일반화해가는 것이 3.6절의 내용입니다.
이렇게 생긴 제한적인 코드가,
vector<int> less_than( const vector<int> &vec, int value ) { vector<int> nvec; for ( int ix = 0 ; ix < vec.size() ; ++x ) if ( vec[ix] < value ) nvec.pushback( vec[ix] ); return nvec; }
타입에 대한 의존성도 없고 백터에 대한 의존성도 없는 이런 코드 바뀝니다.
template<typename InputIterator, typename OutputIterator, typename ElemType, // 비교할 값의 타입 typename Comp> // 비교연산(predicate)의 종류 OutputIterator filter( InputIterator first, InputIterator last, OutputIterator at, const ElemType &val, Comp pred ) { while ( (first = find_if( first, last, bind2nd( pred, val ) )) != last ) { // 무슨 일이 일어나는지를 확인하기 위해 콘솔에 출력 cout << "found value: " << *first << endl; // 값 대입 후 반복자 증가 *at++ = *first++; } return at; }
책은 정렬 후 원하는 조건에 해당하는 값이 처음 나타나는 요소부터 마지막 요소까지 삭제하는 아래와 같은 방법도 소개합니다.
vector<int> sub_vec( const vector<int> &vec, int val ) { vector<int> local_vec(vec); sort( local_vec.begin(), local_vec.end() ); vector<int>::iterator iter = find_if( local_vec.begin(), local_vec.end(), bind2nd( greater<int>(), val )); /////////////////!!!!!!!!///////////////// local_vec.erase( iter, local_vec.end() ); return local_vec; }
또한 이렇게 비템플릿 형태로 구현한 것을 템플릿 함수로 바꾸는 연습을 해보라고 권합니다.
설명이 길었네요.
///////////////!!!!!!!!/////////////// 이 부분이 바로 제가 궁금한 부분입니다.
앞의 filter() 의 경우 <algorithm>에서 제공하는 find_if()함수를 사용하는데 sub_vec()의 경우 컨테이너 멤버함수인 erase()를 사용합니다.
따라서 filter()는 배열의 주소나 벡터, 리스트 등의 컨테이너 반복자를 전달해도 되도록 일반화가 가능했지만 sub_vec()은 배열을 전달할 경우 erase()를 사용할 수 없게 되므로 일반화가 어려워보입니다.
sub_vec()의 백터에 대한 의존성을 없애려면 어떻게 해야하나요?
Forums:
코드가 읽기 힘들게 되서 죄송합니다.
...로 감쌌더니 같은 표현을 & lt; & gt;로 고쳐야 되고, 인덴트도 안되길래 [code]...[/code]를 썼더니 이 보이질 않게 되네요. 고칠 수 있는 방법이 있나요?
완벽한 일반화란 없습니다.
그리고 그것이 Effective STL 의 항목 1(적재적소에 알맞은 container 를 사용하자) 과
항목 2(Container 에 독립적인 code 라는 환상을 조심하자) 입니다.
항목 2 에서는 아예 일반화교(?)에 빠진 당신이라는 말까지 하고 있죠.
반복자 category 가 제공되고 각 container 들의 interface 를 통일하는 이유는
완벽한 일반화를 위한 code 를 작성하는 것이 아닌 적절한 수준에서 일반화를 시키기 위함입니다.
임의접근반복자를 동일하게 제공한다고 해서 배열과 vector, deque 가 항상 동일하게 일반화된 algorithm
code 를 작성할 수 있는 것 또한 아닙니다.
물론 그런 고민은 자신이 작성하고자 하는 algorithm 의 요구조건을 최소화시켜 일반화수준을 향상시키는데
도움을 주지만 그 한계를 파악하는 것도 중요합니다.
-------------------------------------------------------------------------------------------------
서론이 길었는데 단도직입적으로 말해 제시된 code 는 배열과 어울리지 않습니다.
이럴 때 쓰는 방법은 template 특화 정도입니다.
감사합니다.
제가 생각지 못한 방법으로 같은 문제를 해결한 분이 계신가 싶어서 질문드렸는데 역시 무리하게 일반화하려고 들면 안되는 거였군요.
이펙티브 STL을 아직 읽어보지 못했는데 보고 있는 Essential C++과 Accelerated C++을 얼른 마저 보고 읽어봐야겠습니다.
댓글 달기