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