함수객체에 대해서... 도움을 부탁드립니다
글쓴이: doogie / 작성시간: 월, 2005/06/20 - 10:31오후
여러 class의 동일한 이름, 인자의 함수를 미리
stl::map에 등록해놓고 필요할때마다 key를 검색해서
함수를 호출하는 로직을 짜고 있습니다.
테스트 코드를 짜는 중에 어떻게 할지 몰라 이렇게 글을
올립니다.
클래스의 멤버 함수를 호출하고 또 여러 클래스의 멤버함수를
호출하는 거라 함수 포인터 대신에 함수 객체를 이용하고
있습니다.
테스트 환경은 vc++.net입니다.
에러가 나는 소스입니다.
#include "stdafx.h" #include <functional> #include <map> using namespace std; class C1 { public: bool call (int c, string s) { printf ("int : %d, string : %s\n", c, s.c_str ()); printf ("press enter: "); getchar (); return true; } }; class C2 { public: bool call (int c, string s) { printf ("int : %d, string : %s\n", c, s.c_str ()); printf ("press enter: "); getchar (); return true; } }; template <class T> struct functor { public: functor (T t) : X (t) { } bool operator () (int c, string s) const { return X.call (c, s); } private: T & X; }; typedef map <int, functor <class T> > FMap; int _tmain(int argc, _TCHAR* argv[]) { FMap fMap; int c = 1; string s = "this is test"; C1 t1; functor <C1> f1 (t1); fMap.insert (make_pair (1, f1)); //C2 t2; //functor <C2> f2 (t2); //fMap.insert (make_pair (2, f2)); //FMap::const_iterator iter = fMap.find (1); //if (iter != fMap.end ()) // (iter->second) (c, s); return 0; }
VC++의 에러메시지는 다음과 같습니다.
Quote:
error C2664: 'functor<T>::functor(T)' : 매개 변수 1을(를) 'const functor<T>'에서 'T'(으)로 변환할 수 없습니다.
컴파일 중인 함수 템플릿 인스턴스화 'std::pair<_Ty1,_Ty2>::pair<int,functor<T>>(const std::pair<int,functor<T>> &)'에 대한 참조를 확인하십시오.
어떤 부분에서의 잘못으로 에러 메시지가 나오는지 잘 모르겠습니다.
그리고 위의 struct funtor 대신에 boost::function을 사용해도 될듯 한데 어찌 해야 할지도 잘 모르겠습니다.
소스의 잘못된 부분이나 해결책을 가르쳐주시면 감사하겠습니다 ^^
Forums:
[code:1]typedef map <int, functor <
functor<class T> 의 T는 실제 타입 이어야 합니다. functor<C1> 이나 functor<C2> 와 같이 되어야 합니다.
functor<>는 정적 다형성 static polymorphism을 구현하고 있기 때문에 동적 다형성 dynamic polymorphism과 같이 컨테이너에 넣을 수 없습니다.
이런 경우의 일반적인 패턴은 그냥 동적 다형성을 이용하는 것입니다.
C1, C2의 부모 클래스를 만들어서 사용하는 것입니다.
boost::function을 사용하시려면 순수한 functor를 입력값으로 주시던가 boost::bind 등을 사용하셔야 합니다.
제 생각에는 boost::function, boost::bind 를 이용해서 std::map 에 function dispatch 기능을 넣은 것은 부자연스럽게 보이고 복잡합니다.
부족한 제 소견으로 전체 디자인 자체를 바꿔 보시는 것이 좋을 듯 합니다.
간단한 문제이면 문제를 올리시는 것이 더 재미있을 것 같습니다.
ps. 컴파일 시간에 fMap[n] 중 n 이 결정되는 경우는 template Metaprogramming 을 이용할 수도 있습니다.
----------------------------------------
http://moim.at
http://mkhq.co.kr
친절한 답변 감사합니다... :D 이걸 하려는 목적은 네트웍 소
친절한 답변 감사합니다... :D
이걸 하려는 목적은 네트웍 소켓에서 데이터를 받아서 처리할 클래스의 함수를 미리 map에 집어넣고 그때 그때 호출해서 처리하려고 한겁니다.
비동기 소켓이고 Window Programming이다 보니 간단하게
함수포인터 또는 함수객체로 처리하면 쉽겠다 싶어서 코딩하는 중인데 이것도 만만한게 아니군요 :shock:
static 한 class를 map에 넣기 때문에 역시나 안될듯 한 느낌이 오긴 했는데 happyjun 님의 답변을 보니 명확해졌습니다. ^^*
그리고 interface를 만들기는 힘들 듯 하니 boost::function을 사용하는 것도 역시 안될듯 합니다.
이 글을 올리기 전에 boost의 metafunction쪽을 대략 읽어보긴했는데 무슨 말인지 골치아프더군요 ^^*
다시 한번 boost::mpl을 보고 골치를 좀 앓아야 할 듯 합니다. ^^
언제나 처음처럼 ~~
각각의 소켓에서 받은 데이터를 처리한다면 굳이 템플릿을 이용할 필요없이
각각의 소켓에서 받은 데이터를 처리한다면 굳이 템플릿을 이용할 필요없이 동적 다형성을 이용하더라도 문제가 없을 듯 싶군요...
위에 happyjun님이 말씀하신 것처럼 각각의 클래스들을 베이스 클래스로 묶고 함수 객체가 받는 클래스 타입을 베이스 클래스 타입으로 하시는 것이 가장 무난한 선택이 아닌가 생각합니다.
------------------------
http://agbird.egloos.com
댓글 달기