C++代表练习

C++ Delegate Exercise

本文关键字:练习 C++      更新时间:2023-10-16

我一直在做一个小的委托模板练习,以1.)更好地了解自己,2.)更好地理解模板元编程,以及3.)甚至可能将委托用于一些事件驱动的编程(因为我无法访问标准库)。根据这个答案,可以为函数实现以下内容:

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类,它有一个不幸的副作用,即必须在相应的成员函数中指定ReturnTypeParameters的类型。正如我在上面看到的,编译器可以解决这些问题。那么,我该如何让编译器帮我呢?

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
Delegate d(myobj, &MyObj::func);

基本上,这将使Delegate独立于成员函数及其类的类型。只有构造函数模板才能知道返回类型和参数类型。该类没有。您将需要类型擦除,以使委托的类型与内部函数对象的类型无关——基本上,您将实现一个std::function,其实现在这里进行解释(注意,function在返回或参数类型方面是不固定的)。

如果你想要的只是更好的语法和更少的代码冗余,那么就使用一个工厂模板:

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

当使用适当的参数调用时,它会返回一个具有正确初始化的相应类型的Delegate。

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