简体   繁体   English

std :: function到可变参数成员函数,然后绑定可变参数模板参数

[英]std::function to variadic member function and then bind variadic template arguments

I have two variadic class member functions. 我有两个可变参数类成员函数。 When the first one Init(...) is called I want to create a std::function to the second class member function and then bind the arguments of Init(...) to the function pointer. 当第一个Init(...)被调用时,我想为第二个类成员函数创建一个std :: function,然后将Init(...)的参数绑定到函数指针。

So then later on I can just call mf_() without having to pass all arguments to Reset(...) again 因此,稍后我可以调用mf_()而不必再次将所有参数传递给Reset(...)

I'd like to avoid making it template class and store the arguments in a tuple. 我想避免使其成为模板类,并将参数存储在元组中。

I'm trying to make the following example work : 我正在尝试使以下示例工作:

#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;
}

Link to live example : http://cpp.sh/4ylm 链接到实时示例: http//cpp.sh/4ylm

When I compile I get an error that states 编译时出现错误,指出

template argument deduction/substitution failed: 17:37: 模板参数推导/替换失败:17:37:
note: couldn't deduce template parameter '_Result' 注意:无法推断出模板参数“ _Result”

The problem is that &Reset is not a valid pointer-to-member expression. 问题是&Reset不是有效的成员指针指针。

You need to say &Foo::Reset to form a pointer-to-member function, and you also need to supply the this pointer, so you're almost correct with: 您需要说&Foo::Reset来形成一个指向成员的指针函数,并且还需要提供this指针,因此您几乎可以使用:

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

But it's still not valid because Reset is a function template and so you need to say which specialization of the template you mean. 但这仍然无效,因为“ Reset是一个功能模板,因此您需要说出模板的特殊性。

You can tell the compiler which specialization you want by providing an explicit template argument list: 您可以通过提供显式模板参数列表来告诉编译器您想要哪种专业化:

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

Or by creating a variable of the right type, initialized from &Foo::Reset , which allows the compiler to deduce which specialization you mean: 或者通过创建正确的类型的变量(从&Foo::Reset初始化),使编译器可以推断出您要表示的专业化程度:

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

Or by creating a typedef for the right type, and casting &Foo::Reset to that type: 或者通过为正确的类型创建一个typedef,并将&Foo::Reset强制转换为该类型:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM