闭包 class 的可变参数模板 deduction/matching

Variadic template deduction/matching for a closure class

我正在尝试创建一种闭包回调 class 和 运行 解决模板参数推导和匹配的一些问题

( class 的工作原理如下:在构造时,它将把一个成员函数或非成员函数以及一个变量 (CAPARGS) 数量的参数放入一个闭包中。闭包然后可以使用可变数量的参数 (CALLARGS) 调用,它将使用 CAPARGSCALLARGS 调用其回调函数。)

错误 1:

candidate template ignored: could not match 'function' against 'void (*)(int)'

错误 2:

note: candidate template ignored: failed template argument deduction

Class代码:

template <class... CALLARGS>
class Closure{

    public:

        // Constructor intended for use at ERROR 1
        template <class OBJ, class... CAPARGS>
        Closure(OBJ* obj, void (OBJ::*fct)(CAPARGS..., CALLARGS...), CAPARGS... capArgs){
            callback =
                [=] (CALLARGS... callArgs) -> void{
                    (obj->*fct)(capArgs..., callArgs...);
                };
        }

        // Constructor intended for use at ERROR 1
        template <class... CAPARGS>
        Closure(std::function<void(CAPARGS..., CALLARGS...)>, CAPARGS... capArgs){
            callback =
                [=] (CALLARGS... callArgs) -> void{
                    fct(capArgs..., callArgs...);
                };
        }

        void operator () (CALLARGS... callArgs){
            callback(callArgs...);
        }

    private:
        std::function<void(CALLARGS...)> callback;

};

测试代码:

class A{
    public:
        virtual void fct(int a){
            ...
        }
};


void plusF(int a){
    ...
}

int main(void) {

    A a;

    Closure<int> callF(plusF); // **ERROR 1 from here**
    Closure<int> callA(&a, &A::fct); // **ERROR 2 from here**

    callF(1);
    callA(2);

}

我知道我可能正在做超出我能力范围的事情。但我能以某种方式解决这个问题吗?

(顺便说一句,附带问题:将此 class 称为闭包是否合理,或者这样的结构是否有不同的名称?)

您的某些可变参数模板不可扣除(或产生冲突),您可以改为:

template <class... CALLARGS>
class Closure{
public:

    template <class OBJ, typename M, class... CAPARGS>
    Closure(OBJ* obj, M (OBJ::*fct), CAPARGS... capArgs){
        callback =
            [=] (CALLARGS... callArgs) -> void{
                (obj->*fct)(capArgs..., callArgs...);
            };
    }

    template <typename F, class... CAPARGS>
    Closure(F fct, CAPARGS... capArgs){
        callback =
            [=] (CALLARGS... callArgs) -> void{
                fct(capArgs..., callArgs...);
            };
    }
    void operator () (CALLARGS... callArgs){
        callback(callArgs...);
    }
private:
    std::function<void(CALLARGS...)> callback;
};

Demo

std::bind 可能是一个更简单的选择:

using namespace std::placeholders;
A a;

auto callF = std::bind(plusF, _1);
auto callA = std::bind(&A::fct, &a, _1);

callF(1);
callA(2);

Demo