从类模板生成 lambda

sup*_*per 2 c++

我有一个注册回调函数并稍后调用它们的类,看起来像这样。

template<typename ReturnType, typename... Args>
class Signal {
    std::vector<std::function<ReturnType(Args...)>> function;
public:
    template<typename... Args2>
    ReturnType operator()(Args2&&... args2) {
        ReturnType ret;
        for (auto& func : function)
            ret = func(std::forward<Args2>(args2)...);
        return ret;
    }

    template<typename Func>
    void func(Func const &func) {
        function.push_back(std::function<ReturnType(Args...)>(func));
    }

    template<typename Class, typename Instance>
    void mfunc(ReturnType(Class::*func)(Args...), Instance &instance) {
        mfunc2(func, instance, make_int_sequence<sizeof...(Args)>{});
    }
    template<typename Class, typename Instance, int... I>
    void mfunc2(ReturnType(Class::*func)(Args...), Instance &instance, int_sequence<I...>) {
        using namespace std::placeholders;
        function.push_back(std::function<ReturnType(Args...)>(std::bind(func, &instance, placeholder_template<I>{}...)));
    }
};

#include <iostream>

class foo {
public:
    int bar(int x, double y) {
        std::cout << x << " and " << y << std::endl;
        return x*2;
    }
};

int main() {
    foo foo1;
    Signal<int, int, double> sig;
    sig.mfunc(&foo::bar, foo1);
    std::cout << "Return: " << sig(5,5.5) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我今天听到 Stephan T. Lavavej 的演讲,他说的一件事是应该避免使用 std::bind 并使用 lambdas。所以为了学习新东西,我想我会尝试将 mfunc2 中的 std::bind 调用更改为 lambda,但我对模板很陌生,无法弄清楚如何生成我想要的代码。

当前我在 SO 上找到的带有 make_int_sequence 的 placeholder_template ,但我无法真正理解它的工作原理,或者在哪里可以找到任何关于它的好读物......

Args... 保存了 lambda 应该接受的参数类型,但我需要根据 sizeof...(Args) 以某种方式创建变量名称,例如 var1、var2、var3 等,然后将它们合并在一起。

因此,例如 < int, int, int >, Args... 将保存 int, int。然后我想将 lambda 构造为

[func, &instance](int var1, int var2) -> ReturnType { return func(&instance, var1, var2); }
Run Code Online (Sandbox Code Playgroud)

我怎么能做到这一点?

Jod*_*cus 5

这应该可以完成这项工作:

template<typename ReturnType, typename... Args>
class Signal {
    std::vector<std::function<ReturnType(Args...)>> function;
public:
    template<typename... Args2>
    ReturnType operator()(Args2&&... args2) {
        ReturnType ret;
        for (auto& func : function)
            ret = func(std::forward<Args2>(args2)...);
        return ret;
    }

    template<typename Func>
    void func(Func const &func) {
        function.push_back(std::function<ReturnType(Args...)>(func));
    }

    template<typename Class, typename Instance>
    void mfunc(ReturnType(Class::*func)(Args...), Instance& instance) {
        function.push_back([&instance, func](Args&&... args) { 
            return (instance.*func)(std::forward<Args>(args)...); 
        });
    }

};
Run Code Online (Sandbox Code Playgroud)

https://ideone.com/gjPdWN

请注意,在您的 operator() 中,您基本上丢弃了除最后一个之外的所有返回值。这种行为是故意的吗?