class 成员函数的 C++ Functor 模板
C++ Functor template for class member functions
我写了一个小仿函数 class,它应该能够通过隐藏一个静态包装函数和一个指向对象的 void 指针来调用 class 成员函数。由于设置包装器函数时出错,下面的示例无法编译。我想要的是一个 class 成员指针作为模板参数。有谁知道那里出了什么问题吗?
我认为在调用成员函数时静态函数可能存在另一个问题。我不完全知道如何使用模板语法来做到这一点。最小示例使用启用了 C++11 的 gcc 进行编译。
#include <iostream>
template<class TReturn, class... TParameter>
struct Functor {
TReturn (*ptr)(void*, TParameter...);
void *object;
template<class TObject, class TMemberFunction>
static TReturn memberCaller(void *obj, TParameter... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*(TObject::TMemberFunction))(params...);
}
TReturn operator()(TParameter... params) {
return ptr(object, params...);
}
};
class Test {
public:
void func(int a) {
std::cout << a << std::endl;
}
};
int main(int argc, const char **argv) {
Functor<void, int> f;
Test t;
f.object = &t;
f.ptr = &Functor<void, int>::memberCaller<Test, Test::func>;
f(100);
}
这样的事情对你有用吗?
#include <iostream>
template<class TObject, class T, class... TParameter>
struct Functor {
using TMemberFunction = T (TObject::*)(TParameter...);
TMemberFunction ptr;
TObject *object;
T operator()(TParameter... params) {
return (object->*ptr)(params...);
}
};
class Test {
public:
void func(int a) {
std::cout << a << std::endl;
}
};
template<typename T>
class TD;
int main()
{
Functor<Test, void , int> f;
Test t;
f.object = &t;
f.ptr = &Test::func;
f(100);
}
抛开其他一些错误,您的代码不适用于 TMemberFunction
in:
template<class TObject, class TMemberFunction>
static TReturn memberCaller(void *obj, TParameter... params) {
// ...
}
不能用于捕获指向成员函数的指针。 TMemberFunction
必须是一种类型,而您没有那样使用它。
您可以如下定义 class:
template<class>
struct Functor;
template<class TReturn, class... TParameter>
struct Functor<TReturn(TParameter...)> {
TReturn (*ptr)(void*, TParameter...);
void *object;
template<class TObject, TReturn(TObject::*TMemberFunction)(TParameter...)>
static TReturn memberCaller(void *obj, TParameter... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*TMemberFunction)(params...);
}
TReturn operator()(TParameter... params) {
return ptr(object, params...);
}
};
并这样使用:
Functor<void(int)> f;
Test t;
f.object = &t;
f.ptr = &Functor<void(int)>::memberCaller<Test, &Test::func>;
f(100);
也就是说,你现在可以使用成员函数作为memberCaller
的模板参数,让它擦除类型并在调用后在内部使用它。
我还略微更改了 Functor
的定义,以便将其用作:
Functor<void(int)>
当您计划将它与函数类型一起使用时,这比以下内容更明确:
Functor<void, int>
至少我的两分钱。
查看上面的示例和 wandbox 上的 运行。
我写了一个小仿函数 class,它应该能够通过隐藏一个静态包装函数和一个指向对象的 void 指针来调用 class 成员函数。由于设置包装器函数时出错,下面的示例无法编译。我想要的是一个 class 成员指针作为模板参数。有谁知道那里出了什么问题吗?
我认为在调用成员函数时静态函数可能存在另一个问题。我不完全知道如何使用模板语法来做到这一点。最小示例使用启用了 C++11 的 gcc 进行编译。
#include <iostream>
template<class TReturn, class... TParameter>
struct Functor {
TReturn (*ptr)(void*, TParameter...);
void *object;
template<class TObject, class TMemberFunction>
static TReturn memberCaller(void *obj, TParameter... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*(TObject::TMemberFunction))(params...);
}
TReturn operator()(TParameter... params) {
return ptr(object, params...);
}
};
class Test {
public:
void func(int a) {
std::cout << a << std::endl;
}
};
int main(int argc, const char **argv) {
Functor<void, int> f;
Test t;
f.object = &t;
f.ptr = &Functor<void, int>::memberCaller<Test, Test::func>;
f(100);
}
这样的事情对你有用吗?
#include <iostream>
template<class TObject, class T, class... TParameter>
struct Functor {
using TMemberFunction = T (TObject::*)(TParameter...);
TMemberFunction ptr;
TObject *object;
T operator()(TParameter... params) {
return (object->*ptr)(params...);
}
};
class Test {
public:
void func(int a) {
std::cout << a << std::endl;
}
};
template<typename T>
class TD;
int main()
{
Functor<Test, void , int> f;
Test t;
f.object = &t;
f.ptr = &Test::func;
f(100);
}
抛开其他一些错误,您的代码不适用于 TMemberFunction
in:
template<class TObject, class TMemberFunction>
static TReturn memberCaller(void *obj, TParameter... params) {
// ...
}
不能用于捕获指向成员函数的指针。 TMemberFunction
必须是一种类型,而您没有那样使用它。
您可以如下定义 class:
template<class>
struct Functor;
template<class TReturn, class... TParameter>
struct Functor<TReturn(TParameter...)> {
TReturn (*ptr)(void*, TParameter...);
void *object;
template<class TObject, TReturn(TObject::*TMemberFunction)(TParameter...)>
static TReturn memberCaller(void *obj, TParameter... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*TMemberFunction)(params...);
}
TReturn operator()(TParameter... params) {
return ptr(object, params...);
}
};
并这样使用:
Functor<void(int)> f;
Test t;
f.object = &t;
f.ptr = &Functor<void(int)>::memberCaller<Test, &Test::func>;
f(100);
也就是说,你现在可以使用成员函数作为memberCaller
的模板参数,让它擦除类型并在调用后在内部使用它。
我还略微更改了 Functor
的定义,以便将其用作:
Functor<void(int)>
当您计划将它与函数类型一起使用时,这比以下内容更明确:
Functor<void, int>
至少我的两分钱。
查看上面的示例和 wandbox 上的 运行。