向模板类传递通用方法的指针。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了向模板类传递通用方法的指针。相关的知识,希望对你有一定的参考价值。
我想做一个模板类,它的构造函数接受一个对象指针和一个指向对象的一个方法的指针。模板类必须接受一个带有任何参数的方法,所以我认为方法的类型应该是一个模板参数。我也希望接受一个具有任何返回类型的方法,但约束它返回void也可以。下面的代码无法编译。正确的语法是什么?
template <typename Obj, typename Method>
class Foo
{
public:
Foo(Obj *obj, Obj::*Method method)
:mObj(obj), mMethod(method)
{}
void callMethod()
{
mObj->mMethod();
}
private:
Obj* mObj;
Obj::*Method mMethod;
};
class Bar
{
public:
// I want it to work no matter what arguments this method takes.
void method() {}
};
Bar bar;
Foo <Bar, void(Bar::*)()> foo(&bar, &Bar::method);
我在Foo构造函数中得到这个错误。
error C2059: syntax error: '<tag>::*'
我的... 前一个问题 在这个主题上的文章被标记为重复,但所引用的例子指定了可以传递的方法的确切类型,而我需要它是通用的。
答案
首先,你的代码中存在几个语法问题。另外,你不需要 Method
作为模板参数,因为你总是希望传递一个由 Object
类型。
要把可变数量的参数放入 callMethod
,只需提供一个变量参数包给 Foo
. 此外,您还可以推断出该公司的回报类型。callMethod
函数。
把所有这些放在一起,你可以得到。
template <typename Obj, typename Ret, typename ...Args>
class Foo
{
public:
Foo(Obj *obj, Ret (Obj::*method)(Args...))
: mObj(obj), mMethod(method)
{}
Ret callMethod(Args... args)
{
return (mObj->*mMethod)(args...);
}
private:
Obj* mObj;
Ret (Obj::*mMethod)(Args...); // this is essentially 'Method'
};
现在,如果你的类中有一个特定函数的参数数是可变的,它就能正常工作。
class Bar
{
public:
void method() { std::cout << "bar"; }
};
class Car
{
public:
int method2(int, double) {
std::cout << "car";
return 42;
}
};
int main()
{
Bar bar;
Car car;
Foo a (&bar, &Bar::method);
Foo b (&car, &Car::method2);
a.callMethod(); // prints 'bar'
b.callMethod(5, 3.2); // prints 'car'
}
下面是一个工作原理 演示.
请注意,在实际的解决方案中,你可能希望完美转发参数,但这应该让你走上正确的轨道。
另外,在c++17之前,没有CTAD(类模板参数推导),所以你必须在构造时指定模板参数 Foo
对象,像这样。
Foo <Bar, void> a(&bar, &Bar::method);
Foo <Car, int, int, double> b(&car, &Car::method2);
以上是关于向模板类传递通用方法的指针。的主要内容,如果未能解决你的问题,请参考以下文章