c++ - 没有STL和动态内存分配的成员函数类

标签 c++ function templates pointers

我写了下面的例子,它没有使用标准库来调用类成员函数。这按预期工作,但我想让它更通用。这适用于带有 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)...);
    }
};

Demo

我让你用你自己的智能指针替换你想要摆脱标准库的std::shared_ptr

关于c++ - 没有STL和动态内存分配的成员函数类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41869420/

相关文章:

java - JNI/ Kotlin : Is it possible to pass delegate to JNI?

c++ - 非专门模板类中的专门功能

javascript - 从 python 中调用 Javascript 函数,在 html 中调用 Flask 函数

c++ - 令人困惑的模板错误

c++ - 可选模板参数

c++ - 在模板类中使用 shared_from_this

c++ - 海龟图形程序

c++ - 将单词转换为数字的 Switch 语句? C++

javascript - 在 WebView 中调用 JavaScript 函数

javascript - 哈希 Javascript : Prevent '$bind' generation?