C++模板问题与其他参数
问题描述:
我有一个情况(在嵌入式系统上),我想从另一个任务调用函数。我发现这种方法是这样做的http://www.drdobbs.com/elegant-function-call-wrappers/184401385。但我该怎么做更多的争论。最好的情况我有一个解决方案,这是在模板中,但我不知道如何实现这一点。无论如何,也可以创建如下所示的两个太阳穴(在一个小型的Visual Studio C++测试中)。除了给出编译时错误的DeferCall2调用之外,一切正常。我在这里犯了什么错误?C++模板问题与其他参数
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
class Functor
{
public:
virtual ~Functor() {}
virtual void operator()() = 0;
};
template< class CalleePtr, class MemFunPtr, class Parm1 >
class MemberFunctor1 : public Functor
{
public:
MemberFunctor1
(
const CalleePtr & pCallee,
const MemFunPtr & pFunction,
Parm1 aParm1
) :
pCallee(pCallee),
pFunction(pFunction),
aParm1(aParm1)
{
}
virtual void operator()()
{
if ((pCallee != NULL) &&
(pFunction != NULL))
{
((*pCallee).*pFunction)(aParm1);
}
}
private:
CalleePtr pCallee;
MemFunPtr pFunction;
Parm1 aParm1;
};
template< class CalleePtr, class MemFunPtr, class Parm1, class Parm2 >
class MemberFunctor2 : public Functor
{
public:
MemberFunctor2
(
const CalleePtr & pCallee,
const MemFunPtr & pFunction,
Parm1 aParm1,
Parm2 aParm2
) :
pCallee(pCallee),
pFunction(pFunction),
aParm1(aParm1),
aParm2(aParm2)
{
}
virtual void operator()()
{
if ((pCallee != NULL) &&
(pFunction != NULL))
{
((*pCallee).*pFunction)(aParm1, aParm2);
}
}
private:
CalleePtr pCallee;
MemFunPtr pFunction;
Parm1 aParm1;
Parm2 aParm2;
};
template< class CalleePtr, class Callee, class Ret, class Type1, class Parm1 >
inline Functor * DeferCall
(
const CalleePtr & pCallee,
Ret(Callee::*pFunction)(Type1),
const Parm1 & rParm1
)
{
return new
MemberFunctor1< CalleePtr,
Ret(Callee::*)(Type1), Parm1 >
(pCallee, pFunction, rParm1);
}
template< class CalleePtr, class Callee, class Ret, class Type1, class Parm1, class Parm2>
Functor * DeferCall2
(
const CalleePtr & pCallee,
Ret(Callee::*pFunction)(Type1),
const Parm1 & rParm1,
const Parm2 & rParm2
)
{
return new
MemberFunctor2< CalleePtr,
Ret(Callee::*)(Type1), Parm1, Parm2 >
(pCallee, pFunction, rParm1, rParm2);
}
class TestObj
{
public:
void test1 (int a)
{
printf("test 1 a=%d\r\n", a);
}
void test2 (int a, int b)
{
printf("test 2 a=%d, b=%d\r\n", a, b);
}
void test (void)
{
Functor * pCall = DeferCall(this, &TestObj::test1, 3);
Functor * pCall1 = new MemberFunctor1 < TestObj *, void (TestObj::*)(int), int >(this, &TestObj::test1, 6);
Functor * pCall2 = new MemberFunctor2 < TestObj *, void (TestObj::*)(int, int), int, int >(this, &TestObj::test2, 4, 5);
Functor * pCall3 = DeferCall2(this, &TestObj::test2, 3, 3); // Compile time error.
if (pCall)
(*pCall)();
if (pCall1)
(*pCall1)();
if (pCall2)
(*pCall2)();
if (pCall3)
(*pCall3)();
delete pCall;
delete pCall1;
delete pCall2;
delete pCall3;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TestObj *obj = new TestObj();
obj->test();
delete obj;
return 0;
}
答
你忘了在函数的第二个int型参数:
template <class CalleePtr, class Callee, class Ret, class Type1, class Parm1, class Parm2>
Functor* DeferCall2(const CalleePtr& pCallee, Ret (Callee::*pFunction)(Type1, Type1), const Parm1& rParm1,
const Parm2& rParm2) {
return new MemberFunctor2<CalleePtr, Ret (Callee::*)(Type1, Type1), Parm1, Parm2>(pCallee, pFunction, rParm1, rParm2);
}
的变化是在这里:
Ret (Callee::*pFunction)(Type1, Type1)
^^^^^^^
出现的两个地方或者如果第二个类型不总是与第一个类型相同,则添加另一个模板参数。
主叫仿函数有两个整数:void (TestObj::*)(int, int)
答
要调用:
DeferCall2(this, &TestObj::test2, 3, 3);
其中&TestObj::test2
具有类型void (TestObject::*)(int, int)
。的DeferCall2
的签名具有不必要的许多模板的参数,但它需要的第二个参数的类型是:
Ret(Callee::*pFunction)(Type1)
也就是说,一个指向非CV-合格的,非可变参数构件函数,它一个参数。因此扣除失败。你错过了第二种类型。
注意,你只是有效地重新实现std::bind
:
auto call3 = std::bind(this, &TestObj::test2, 3, 3);
call3();