1

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

所以再后来我可以叫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'

+0

请不要在您的问题中编辑解决方案。 – Barry

回答

1

问题是&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...); 

或者通过创建正确类型的类型定义,和铸造&Foo::Reset该类型:

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

谢谢!这是工作。用实时解决方案演示更新我的原始问题 – Ody

相关问题