c++ - 存储和调用具有未知参数的成员函数

标签 c++ lambda c++17 template-meta-programming

我正在尝试存储一个未知类的成员函数,其中包含未知参数以供稍后调用。

我找到了这个代码片段来获取 lambda:

template <auto Fn, typename T, typename R = void, typename... Args>
auto get_cb_inner(T* obj, R (T::*)(Args...) const) {
    return [obj](Args... args) -> R {
        return (obj->*Fn)(std::forward<Args>(args)...);
    };
}
template <auto Fn, typename T>
auto get_cb(T* obj) {
    return get_cb_inner<Fn, T>(obj, Fn);
}

但我不知道如何存储它,然后才能在运行时使用正确的参数调用它。

我有一个这样的结构:

struct Job {
    void execute(Data& data, const OtherData& otherData) const {
       // do job
    }
};

auto exe_fn = get_cb<&Job::execute>(new Job());

我想做的是将这个“执行”函数存储在一个 lambda 中,然后将它存储在一个可以迭代和调用的类似 vector 的容器中(与其他可能具有不同参数的函数)。

编辑:

我使用@KamilCuk 代码创建了这个没有内存泄漏/段错误的包装器结构。

template <typename... Args>
using exec_fn = std::function<void(Args...)>;
template <typename Job>
using job_ptr = std::unique_ptr<Job>;

template <typename J, typename R = void, typename... Args>
struct JobExecuteCaller {
    exec_fn<Args...> exec_fn;
    job_ptr<J> job_ptr;
    JobExecuteCaller (J* job, R (S::*f)(Args...) const)
        : job_ptr{job_ptr<J>(job)} {
        exec_fn = [this, f](Args... args) -> R {
            (job_ptr.get()->*f)(std::forward<Args>(args)...);
        };
    }
    void operator()(Args... args) { exec_fn(args...); }
};

auto process = JobExecuteCaller(new Job(), &Job::execute);
JobExecuteCaller(/*args ... */)

现在我只需要找出一种方法来存储不同类型的 JobExecuteCallers。

最佳答案

你是说你想要std::bind

#include <utility>
#include <new>
#include <iostream>
#include <functional>

struct Job {
    void execute(int a, int b) {
       std::cout << a << " " << b << std::endl;
    }
};

int main() {
    auto exe_fn = std::bind(&Job::execute, new Job(), 
        std::placeholders::_1, std::placeholders::_2);
    exe_fn(1, 2);
}

我已经修复了你的代码。您不仅需要将函数成员指针的类型传递给函数,还需要将函数成员指针的地址传递给函数。这样你就可以调用它了。

#include <utility>
#include <new>
#include <iostream>
#include <functional>

template <typename T, typename R = void, typename... Args>
auto get_cb(T* obj, R (T::*f)(Args...)) {
    return [obj, f](Args... args) -> R {
        return (obj->*f)(std::forward<Args>(args)...);
    };
}

struct Job {
    void execute(int a, int b) {
        std::cout << a << " " << b << std::endl;
    }
};

int main() {
    auto exe_fn = get_cb(new Job(), &Job::execute);
    exe_fn(1, 2);
}

请注意,这两个示例都从 new Job() 中泄漏了内存。

关于c++ - 存储和调用具有未知参数的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55571873/

相关文章:

c++ - Clang 无法使用模板元编程编译参数包扩展

c# - Lambda 表达式返回错误

c++ - 链表的 Lambda 长度

c++ - 在 C++17 中定义可变坐标(元组)类型?

c++ - 从静态成员函数推断类模板参数的模式

c++ - 使用返回 constexpr 对进行模板实例化

c++ - QT .UI 显示.GIF?

c++ - 错误 : "undefined reference to ' function'"in C++

c++ - 自定义排序算法c++

python - lambda 函数如何在 python 中引用它的参数?