std::函数到varadic成员函数,然后绑定varadic模板参数

std::function to variadic member function and then bind variadic template arguments

本文关键字:varadic 函数 参数 绑定 成员 std 然后      更新时间:2023-10-16

我有两个可变类成员函数。当调用第一个Init(...)时,我想为第二个类成员函数创建一个std::函数,然后将Init(...)的参数绑定到函数指针。

所以稍后我可以调用mf_(),而不必再次将所有参数传递给Reset(...)

我希望避免将其作为模板类,并将参数存储在元组中。

我正在尝试使以下示例起作用:

#include <iostream>
#include <string>
#include <functional>
using namespace std;
class Foo
{
public:
    template<typename... T>
    void Init(T&... args)
    {
        cout << __func__ << endl;
        Print(args...);
        // bind args.. to Reset ..
        mf_ = std::bind(&Reset, args...);
       // mf_ = std::bind(&Foo::Reset, this, args...); ???
    }
    template<typename... T>
    void Reset(T&... args)
    {
        cout << __func__ << endl;
    }
    // std::function to Reset(...)
    std::function<void()> mf_;
private:
    template<typename First>
    void Print(First& arg)
    {
        cout << arg << endl;
    }
    template<typename First, typename... Rest>
    void Print(First& arg, Rest&... args)
    {
        cout << arg << " ";
        Print(args...);
    }
};
int main() 
{
    int arg1 = 1;
    int arg2 = 2;
    string arg3 { "test" };
    double arg4 = 1.10;
    Foo foo;
    foo.Init(arg1, arg2, arg3, arg4);
    //foo.mf_();
    return 0;
}

链接到实际示例:http://cpp.sh/4ylm

当我编译时,我得到一个错误,状态为

模板参数推导/替换失败:17:37:
注意:无法推导模板参数"_Result"

问题是&Reset不是指向成员表达式的有效指针。

您需要说&Foo::Reset来形成指向成员函数的指针,并且还需要提供this指针,因此使用几乎是正确的

   // mf_ = std::bind(&Foo::Reset, this, args...); ???

但它仍然是无效的,因为Reset是一个函数模板,所以你需要说明你指的是模板的哪个专业化。

您可以通过提供显式模板参数列表来告诉编译器您想要哪个专业化:

mf_ = std::bind(&Foo::Reset<T&...>, this, args...);

或者通过创建一个正确类型的变量,从&Foo::Reset初始化,这允许编译器推断出您所指的专业化:

void (Foo::*f)(T&...) = &Foo::Reset;
mf_ = std::bind(f, this, args...);

或者为正确的类型创建一个typedef,并将&Foo::Reset强制转换为该类型:

   using pmf_type = void (Foo::*)(T&...);
   mf_ = std::bind((pmf_type)&Foo::Reset, this, args...);