STL 고수님들 봐주세요. ( mem_fun_ref 관련 )
글쓴이: freezm7 / 작성시간: 화, 2004/06/01 - 5:23오후
#include <vector> #include <set> #include <map> #include <iterator> #include <functional> #include <algorithm> using namespace std; // 생략 ... set<set<int> > grps; int x; set<set<int> >::iterator x_iter = find_if(grps.begin(), grps.end(), bind2nd(mem_fun_ref(&set<int>::count), x));
마지막 줄이 자꾸 컴파일 에러가 납니다.
혼자서 계속 머리 굴려봤는데, 해답이 안 떠오르네요.
STL 고수님, 잠시만 훑어봐 주세요.
그나저나 STL 의 매력이 장난 아니네요. :D
Forums:


[code:1]set<set<int> >:&
set<set<int> >::iterator x_iter = find_if(grps.begin(), grps.end(), bind2nd(mem_fun_ref(&set<int>::count), x));아마 의도한 것은 set<int> 중에서 x 를 가지고 있는 것을 찾으려는 것으로
생각됩니다.
일단 bind2nd는 적용할 수 없습니다. bind2nd는 매개변수2개를 받는
함수의 두번째 매개변수를 고정시켜 매개변수 한개를 받는 함수로 만드는
어댑터입니다. 그런데 set<int>::count 는 매개변수를 하나만 받으므로
적용하려면 당연히 에러가 납니다.
제 생각에는 간단하게 조건함수객체를 하나 만들면 될 듯 합니다.
template<class T> struct Temp { private : T x; public: Temp(T v) { x = v; } bool operator()( const std::set<T> & s ) { return s.count(x); } };set<set<int> >::iterator x_iter = find_if(grps.begin(), grps.end(), Temp<int>(x) );테스트는 안해봤는데 아마 잘 동작할 겁니다.
결과적으로 해결책은 되었으나 다음은 잘못 알고 계십니다.[quot
결과적으로 해결책은 되었으나 다음은 잘못 알고 계십니다.
mem_fun_ref나 mem_fun에서 첫번째 인자는 그 멤버를 부르는
클래스 개체 또는 그에 대한 포인터를 뜻합니다. 즉
mem_fun(&C::f)(p, x) 는 p->f(x) 로,
mem_fun_ref(&C::f)(p, x) 는 p.f(x) 로 해석됩니다. 따라서
struct S { void f(int) const { } }; int main() { vector<S> v; for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&S::f), 1)); // 문장 1 for (vector<S>::iterator it = v.begin(); it != v.end(); ++it) // 문장 2 it->f(1); }에서 문장 1과 2가 수행하는 내용은 동일합니다.
원래 코드가 에러나는 이유에 대해서는 저도 확실히 알지 못합니다. 저도
비슷한 일을 겪은 적이 있는데 아마 참조형과 관련된 것이 아닐까 추측만
하고 있습니다. 이번 기회에 확실히 알아봐야겠군요.
[quote="doldori"]결과적으로 해결책은 되었으나 다음은 잘못
알려주셔서 감사합니다. 제가 잘못알고 있었네요..
저도 확실히는 모르겠으나 아마 참조에 대한 참조의 문제로 컴파일이 안되는듯
합니다.
올리신 예제 코드에서
void f(int) const { }를void f(const int &) const { }로 바꾸면 컴파일에러가 납니다.dev-c++ 에서는 bind2nd 가 다음 처럼 정의되어 있습니다.
두번째 매개변수를 참조형으로 받습니다.
그런데 내부적으로 S::f(int)를 호출할 때 이 함수도 참조형을 받으므로
참조의 참조가 되어 에러가 나는 것으로 보입니다.
원래 질문하신분의 코드에서
set<T>::count 도 역시 참조를 받습니다. 아마 이게 문제인듯...
알아본 결과 exsider 님이 지적한 대로 참조형의 참조가 문제였습니다
알아본 결과 exsider 님이 지적한 대로 참조형의 참조가 문제였습니다.
자세한 내용은
http://www.boost.org/libs/functional/binders.html
의 references to references 항목을 참고하세요.
Boost에서 이에 대한 해결책을 제시하고 있습니다.
원래 코드를 고친다면
#include <boost/functional.hpp> set<set<int> > grps; int x; set<set<int> >::iterator x_iter = find_if(grps.begin(), grps.end(), boost::bind2nd(boost::mem_fun_ref(&set<int>::count), x));가 되겠네요.
감사합니다.
이렇게까지 자세한 설명이 나오리가 기대하진 못했습니다. :D
아무튼 이 부분이 active issue list에 올라 있다니, 언젠가는 고쳐질 듯 하군요. :lol:
STL 사랑합시다~
즐겁게 살아 볼까나~*
댓글 달기