c – std :: function就像委托模板类一样
发布时间:2020-12-16 09:49:31 所属栏目:百科 来源:网络整理
导读:您好我正在尝试编写一个委托类,可以采取类似于标准函数签名的模板参数,并为成员函数指针创建一个委托,如下面的主要部分所示.代码可能过于简单,但我正在寻找的是一个简单而快速的解决方案,尽可能减少开销.我认为如果我可以在没有运行时多态性的情况下获得类中
您好我正在尝试编写一个委托类,可以采取类似于标准函数签名的模板参数,并为成员函数指针创建一个委托,如下面的主要部分所示.代码可能过于简单,但我正在寻找的是一个简单而快速的解决方案,尽可能减少开销.我认为如果我可以在没有运行时多态性的情况下获得类中的类型T,那么这个实现非常接近于实现我想要的.
template<class T> struct FastDelegate {}; template<class R,class... Args> struct FastDelegate<R (Args...)> { template <typename T> FastDelegate(T* t,R (T::*f)(Args...)) : m_t(t),m_f(f) {} R operator()(Args... p) { return (m_t->*m_f)(std::forward<Args>(p)...); } T* m_t; // How can I capture T as a type in this partial specialization? R (T::*m_f)(Args...); }; struct Test { int add ( int x,int y ) { return x+y; } }; int main () { int x = 5; int y = 4; Tester t; FastDelegate<int (int,int)> d (&t,&Test::calc ); int z = d(x,y); } 解决方法
您可以将对象捕获为void *,将成员函数存储在随机成??员函数类型中,并具有恢复必要类型的函数.这种方法避免在堆上分配任何内存.有问题的步骤是从某种类型的成员函数转换到另一个成员函数.但是,根据5.2.10 [expr.reinterpret.cast]第10段,只要成员函数在使用之前被转换回其原始类型,就可以安全地使用这种方法:
下面是一个实现此方法的示例.但是,请注意,使用std :: function< R(Args ...)>可能更容易.使用合适的lambda作为标准库可能会首先实现类似的方法. #include <iostream> #include <utility> template<class T> struct FastDelegate {}; template<class R,class... Args> struct FastDelegate<R (Args...)> { struct dummy {}; template <typename T> FastDelegate(T* t,R (T::*f)(Args...)) : m_t(t),m_f(reinterpret_cast<void (dummy::*)()>(f)),m_call([](void(dummy::*d)(),void* v,Args... a){ typedef R (T::*mem)(Args...); T* t = static_cast<T*>(v); mem f = reinterpret_cast<mem>(d); return (t->*f)(std::forward<Args>(a)...); }) { } R operator()(Args... p) { return (this->m_call)(this->m_f,this->m_t,std::forward<Args>(p)...); } void* m_t; void (dummy::*m_f)(); R (*m_call)(void (dummy::*)(),void*,Args...); }; struct Tester { int add ( int x,int y ) { std::cout << "add(" << x << "," << y << ")n"; return x+y; } }; int main () { int x = 5; int y = 4; Tester t; FastDelegate<int (int,&Tester::add); int z = d(x,y); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |