2014-11-05 5 views
2

나는 작은 대리인 연습 문제를 만들기 위해 노력 해왔다. 1.) 나 자신을 더 잘 이해하고, 2. 템플릿 메타 프로그래밍을 잘 이해하고, 3.) 이벤트 위주 프로그래밍을 위해 델리게이트를 사용하기도했다. 나는 표준 라이브러리에 접근 할 수 없다.) this 대답에 따르면, 다음과 같은 함수 구현 될 수C++ 대리인 연습

template <typename T, typename R, typename ...Args> 
R proxycall(T & obj, R (T::*mf)(Args...), Args &&... args) 
{ 
    return (obj.*mf)(args...); 
} 

proxycall(myobj, &MyObj::func); 

그것은 컴파일러가 리턴 타입, 클래스 유형 및 매개 변수 유형을 알아낼 수있는 것처럼 보인다 단지 템플릿에 myobj&MyObj::func를 전달하여 . 위와 같은 메서드를 사용하여 대리자 클래스 (개체에 대한 참조와 멤버 함수에 대한 포인터를 모두 저장하는 클래스)를 만들 수 있습니까?

Delegate d(myobj, &MyObj::func); /* Preferred */ 

또는

Delegate<myobj, &MyObj::func> d; /* Ok */ 

다음 클래스 내 Delegate 클래스이며, 이는 ReturnType를 지정할 필요 불행한 부작용과 해당 멤버 함수의 Parameters의 형태를 갖는다. 위에서 보았 듯이, 컴파일러는 그 것을 알아낼 수 있습니다. 그렇다면 컴파일러에서 어떻게 도와 줄 수 있습니까?

template <class Class, typename ReturnType, typename ... Parameters> 
class Delegate { 
    public: 
     typedef ReturnType (Class::*Method)(Parameters ... params); 

     Delegate(Class& ref, Method m) : obj(ref), method(m) {} 
     ReturnType operator()(Parameters ... params) { return (obj.*method)(params...); } 
     ReturnType Invoke(Parameters ... params) { return operator()(params...); } 
    private: 
     Class& obj; 
     Method method; 
}; 

/* Usage */ 
Delegate<MyObj, void> d(myobj, &MyObj::func); 
     ^^^^^^^^^^^ 
      ick 
+0

나는'당신이 ...'표준 앞으로 (인수를) :: ...'대신'인수의가 있어야 proxycall''에서, 틀리지 않는 경우. – cdhowie

답변

2
Delegate d(myobj, &MyObj::func); 

기본적으로이 멤버 함수와 클래스의 형식에서 Delegate 독립적으로 만들 것입니다. 생성자 템플릿 만 반환 형식과 매개 변수 형식을 알 수 있습니다. 수업은 그렇지 않습니다. 델리게이트 유형을 내부 함수 객체의 유형과 독립적으로 만들려면 이터 레이를 입력해야합니다. 기본적으로 구현은 here (반환 또는 매개 변수 유형의 측면에서 고정되어 있지 않음)으로 구현되는 std::function을 구현합니다. 당신이 원하는 모든이 더 좋은 구문 및 코드에 덜 중복 인 경우

, 공장 템플릿을 사용

적절한 인수로 호출 할 때, 제대로 초기화 해당 유형의 위임을 반환
template <typename T, typename R, typename ...Args> 
Delegate<T, R, Args...> make_delegate(T& obj, R (T::*mf)(Args...)) 
{ 
    return {obj, mf}; 
} 

.

auto deleg = make_delegate(myobj, &MyObj::func); 
+0

Delegate 에서'T'를 원하지 않는다고 생각합니다. 그것은 당신이 전에 말한 모든 것에 반대한다. :) – Barry

+0

@ Barry 나는 거기에'T'를 원한다. 나는 그의 * 클래스를위한 공장을 제공했다. 잘못된 위치에 있었지만, 힌트를 주셔서 감사합니다. – Columbo

+0

'Delegate d'; 이것은 가능한가? 템플릿 매개 변수로 클래스에 대한 참조와 멤버에 대한 포인터 함수에 대한 참조를 전달할 수 있습니까? – thndrwrks