2014-11-05 83 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'你应该有'的std ::向前(参数)...',而不是'ARGS ...'。 – cdhowie 2014-11-05 18:13:14

回答

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

基本上,这会使得Delegate独立于成员函数和它的类的类型。 只有构造函数模板才会知道返回类型和参数类型。班级没有。您将需要类型擦除,使委托独立的内部函数对象的类型的类型 - 基本上你会实现一个std::function其实现解释here(注意: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

我不认为你想在'委托'T' '。这违背了你才当即表示一切:) – Barry 2014-11-05 18:37:21

+0

@Barry我确实想在那里'T',我只是提供了* *了类工厂。这是错误的立场,谢谢你的提示。 – Columbo 2014-11-05 18:41:27

+0

约'代表什么 D';这甚至有可能吗?我可以将对类的引用和指向成员的指针作为模板参数传递吗? – thndrwrks 2014-11-05 18:45:31