C++로 지연된 함수콜 구현하기

지난 2일 간

관해서 포스팅했다. 오늘 이걸 실제로 광범위하게 적용시켜봤는데, 그러다 보니 문제점들이 확실히 보였다(…).

테스트 하는 동안 가장 문제가 되었던 것은 참조형으로 넘겨준 변수 문제였다. (포인터로 넘겨주는 일은 "없다고 가정하는 상황"이라서 일단 그 문제는 넘어가자 :p )

class A : private boost::noncopyable
{
public:
    A() {}
    virtual ~A() {}    
    void Do3( int a, int b, int& c ){
        cout << "A::Do3( " << a << ", " << b << ", " << c << " )" << endl;
    }    
};
 
void foo()
{
    A a;
    int tmp_val = 3;
    shared_ptr<Closure> c = MakeClosure< A, void, int, int, int& >( a, &A::Do3, 1, 2, tmp_val );
    c->Execute();
    tmp_val = 0;
    c->Execute();
}

 
foo 의 실행결과는 다음과 같다. (foo에서 Closure를 만드는 부분의 타입 추론 문제 때문에 템플릿 인자를 명시적으로 썼다)

A::Do3( 1, 2, 3 )

A::Do3( 1, 2, 0 )

지금 구현한 것을 사용하는 곳에서 원하는 동작은 두 번의 실행 모두 (1, 2, 3) 이라고 찍히는 것이다.  템플릿 클래스 멤버 변수들의 타입을 실행될 함수의 인자타입과 동일하게 했었는데, 이를 참조자 형태인 경우에만 원래의 타입이 되게 수정하는 코드를 넣었다. 즉, 원래

A0 m_A0;

A1 m_A1;

처럼 선언되던 것을, boost::remove_reference<T> 를 사용해서†

typename boost::remove_reference<A0>::type m_A0;

typename boost::remove_reference<A1>::type m_A1;

로 선언되게 수정했다. 그러고 나니 원하는 대로의 출력이 나오게 되었다.

이제 남은 문제: MakeClosure 라는 보조 함수를 통해서 템플릿 인자 타입을 자동 연역하게 했었는데, 참조형인 경우에는 이게 제대로 되지 않는다. 뭘 해주면 이걸 자동으로 찾을까?-_-; 즉, 위에 사용한 코드의 MakeClosure 부분의 템플릿 인자 목록을 지우면,

int인지 int&인지 모호하다.

라는 에러가 나오게 되는데(VC++ 2005기준) 이를 피할 방법은 없을까? 라는 것.

*

† boost::remove_reference<T>는 <boost/type_traits/remove_reference.hpp>에 정의되어 있다.

T가 어떤 타입 U의 참조형(U&)일 때만 U로 바꿔준다. T가 그렇지 않은 타입인 경우 그대로 T를 돌려주게 된다.

 

Author: rein

나는 ...

1 thought on “C++로 지연된 함수콜 구현하기”

  1. Pingback: rein's world

Leave a Reply