c++ - std::c++ 静态分配函数

标签 c++ lambda type-erasure

我在一个内存受限的嵌入式环境中工作,在该环境中,malloc/free new/delete 是不可取的,我正在尝试使用 std::function 模式来注册回调。我无法访问我的目标代码中的任何 STL 方法,因此我很不幸,不得不自己复制一些 STL 功能。由于调用者需要进行捕获,函数指针对我来说不是一个选项。

例如,我想声明一个可以注册 onChange 事件的 Mailbox 类

class Mailbox {
    std::function<void(int,int)> onChange;
};

这样,调用者就可以注册一个 lambda onChange 处理程序,它可以捕获这个或其他对处理事件很重要的变量。

由于这是 API 的一部分,我想为 Mailbox 的用户提供最大的灵 active ,以提供函数指针、lambda 或仿函数。

我设法找到了 great implementation std::function 的开销看起来特别低,除了涉及动态内存外,它完全符合我的需要。

如果你看下面的代码,动态内存只用在一个地方,而且它似乎完全限定在被模板化的对象范围内,这表明它的大小应该在编译时就知道。

谁能帮我理解如何重构此实现,使其完全静态并删除对 new/malloc 的使用?我无法理解为什么在编译时无法计算 CallableT 的大小。

下面的代码(不适合胆小的人)。请注意,它使用 make_unique/unique_ptr 但这些可以很容易地替换为 new 和 * 并且我已经成功测试了该用例。

#include <iostream>
#include <memory>
#include <cassert>
using namespace std;

template <typename T>
class naive_function;

template <typename ReturnValue, typename... Args>
class naive_function<ReturnValue(Args...)> {
public:
    template <typename T>
    naive_function& operator=(T t) {
        callable_ = std::make_unique<CallableT<T>>(t);
        return *this;
    }

    ReturnValue operator()(Args... args) const {
        assert(callable_);
        return callable_->Invoke(args...);
    }

private:
    class ICallable {
    public:
        virtual ~ICallable() = default;
        virtual ReturnValue Invoke(Args...) = 0;
    };

    template <typename T>
    class CallableT : public ICallable {
    public:
        CallableT(const T& t)
            : t_(t) {
        }

        ~CallableT() override = default;

        ReturnValue Invoke(Args... args) override {
            return t_(args...);
        }

    private:
        T t_;
    };

    std::unique_ptr<ICallable> callable_;
};

void func() {
    cout << "func" << endl;
}

struct functor {
    void operator()() {
        cout << "functor" << endl;
    }
};

int main() {
    naive_function<void()> f;
    f = func;
    f();
    f = functor();
    f();
    f = []() { cout << "lambda" << endl; };
    f();
}

编辑:添加了对 STL 的说明

最佳答案

您要查找的名称是“in-place function”。现在至少有一个非常好的实现:

还有 tj::inplace_any<Size, Align> , 如果你需要/想要 any 的语义.

关于c++ - std::c++ 静态分配函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45088723/

相关文章:

c++ - 类的非静态成员函数的函数指针

android - Kotlin 多层 IT 引用

scala - 多态类型的类型类遭受类型删除

c++ - 在父窗口中限制可拖动的子窗口?

c++ - QML 中的两种方式绑定(bind) C++ 模型

java - BiFunction - apply 方法应该总是返回第二个参数。为什么?

java - 你可以 "dynamically bind"重载方法吗?

Swift:为符合通用协议(protocol)的通用类创建包装类时出错

C++ 零初始化

python - 在 Numpy 中执行积分时出现 ValueError