我写了下面的例子,它没有使用标准库来调用类成员函数。这按预期工作,但我想让它更通用。这适用于带有 8 位微 Controller 的嵌入式系统。我不想引发关于是否为这种架构使用 C++ 的讨论。
代码的工作原理如下:对类成员函数或函数使用 void 指针是不可能的。虽然可以对单个函数使用 void 指针,但这不是明确定义的行为。
在这种情况下,我使用静态函数来调用类成员。方法调用函数是一个静态模板函数,它接受对象类型和成员函数指针作为模板参数。
bind 函数将对象指针存储为void 指针,并将类内部的callingFunction 设置为特定的静态方法。当使用 () 运算符进行调用时,将使用特定对象和所有参数调用 callingFunction 指针。
所有这些都按预期工作,并且由于可变参数模板,可以在启用 C++11 的情况下进行编译。我的目的是让 api 更舒适。一直使用 f.bind(&t) 似乎有点长,但我不知道有什么更好的方法来做到这一点。有任何想法吗?
还有一点就是存储函数,函数不是类的一部分。
#include <iostream>
class testclass {
public:
virtual char test(void){
return '.';
}
};
class testclass2 : public testclass{
public:
char test(void){
return '@';
}
};
template<typename signature>
class Function;
template<typename TReturn, typename ...TParam>
class Function<TReturn(TParam...)> {
public:
template<typename TObject, TReturn (TObject::*TMethod)(TParam...)>
void bind(TObject *obj){
this->obj = obj;
this->callingFunction = &methodCaller<TObject, TMethod>;
}
TReturn operator()(TParam... params){
return callingFunction(this->obj, params...);
}
private:
void *obj;
TReturn (*callingFunction)(void *obj, TParam...);
template<typename TObject, TReturn (TObject::*TMethod)(TParam...)>
static TReturn methodCaller(void *obj, TParam... params) {
TObject *c = static_cast<TObject*>(obj);
return (c->*TMethod)(params...);
}
};
int main(){
testclass t;
Function<char(void)> f;
f.bind<testclass, &testclass::test>(&t);
std::cout << f();
testclass2 t1 = testclass2();
f.bind<testclass, &testclass::test>(&t1);
std::cout << f();
}
最佳答案
下面允许你期望的界面
template<typename signature> class Function;
template<typename TReturn, typename ...TParam>
class Function<TReturn(TParam...)> {
private:
template <typename Obj>
struct Helper
{
Obj* obj;
TReturn (Obj::*m)(TParam...);
Helper(Obj* obj, TReturn (Obj::*m)(TParam...)) : obj(obj), m(m) {}
template <typename ... Args>
TReturn call(Args&&... args) { return (obj->*m)(std::forward<Args>(args)...); }
};
public:
template<typename TObject>
void bind(TObject *obj, TReturn (TObject::*m)(TParam...)){
this->obj = std::make_shared<Helper<TObject>>(obj, m);
this->callingFunction = &methodCaller<TObject>;
}
TReturn operator()(TParam&&... params){
return callingFunction(this->obj.get(), std::forward<TParam>(params)...);
}
private:
std::shared_ptr<void> obj;
TReturn (*callingFunction)(void* obj, TParam...);
template<typename TObject>
static TReturn methodCaller(void *obj, TParam... params) {
auto* c = static_cast<Helper<TObject>*>(obj);
return c->call(std::forward<TParam>(params)...);
}
};
我让你用你自己的智能指针替换你想要摆脱标准库的std::shared_ptr
。
关于c++ - 没有STL和动态内存分配的成员函数类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41869420/