2016-07-15 54 views
3

我有一些代碼(GitHub上的progschj提供),我已經適應了我的問題。 MakeTask將任何函數及其參數移動到MakeTask中,這會生成packaged_task。創建的任務隨即執行,其未來將返回給調用者。這非常漂亮,但我希望能夠用成員函數來做到這一點。但是,如果我將Func放入結構中,MakeTask中的F & &將失敗,並顯示代碼中提到的錯誤。一個成員函數可以在任何使用std :: function的自由函數中使用嗎?

#include <future> 
#include <memory> 
#include <string> 
#include <functional> 

template<class F, class... Args> 
auto MakeTask(F&& f, Args&&... args)-> std::future< typename std::result_of< F(Args...) >::type > 
{ 
    typedef typename std::result_of< F(Args...) >::type return_type; 

    auto task = std::make_shared< std::packaged_task< return_type() > >(
    std::bind(std::forward<F>(f), std::forward<Args>(args)...) 
    ); 

    std::future<return_type> resultFuture = task->get_future(); 

    (*task)(); 

    return resultFuture; 
} 

struct A 
{ 
    int Func(int nn, std::string str) 
    { 
    return str.length(); 
    } 
}; 

int main() 
{ 
    // error C2893: Failed to specialize function template 'std::future<std::result_of<_Fty(_Args...)>::type> MakeTask(F &&,Args &&...)' 
    // note: 'F=int (__thiscall A::*)(int,std::string)' 
    // note: 'Args={int, const char (&)[4]}' 
    auto resultFuture = MakeTask(&A::Func, 33, "bbb"); // does not compile 

    int nn = resultFuture.get(); 

    return 0; 
} 

如果我將Func變成靜態,但是會破壞我的應用程序代碼的其他部分,我可以使它工作。

編輯1:我想出了std :: function的語法,並用新的錯誤信息修改了示例。 MakeTask的F & &移動參數不接受我的aFunc作爲可調用對象。編輯2:由於Barry的回答,我將示例代碼更改回原始發佈,以便他的回答對未來的觀衆有意義。

+0

你期望代碼得到調用'Func'所需的'A'實例? – aschepler

+3

簽出'std :: bind' – NathanOliver

+0

@aschepler第一個MakeTask arg應該是&A :: Func,而不是A,以產生錯誤消息。 – rtischer8277

回答

3

&A::Func是一個非靜態成員函數,這意味着它需要一個A的實例來操作。所有函數對象/適配器使用的約定是,第一個參數將是該實例。

MakeTask()要求使用所有其他參數(Args...)可調用第一個參數(F)。 &A::Func要求三個自變量:A類型的對象(或指向Areference_wrapper<A>的對象),intstring。你只是錯過了第一個:

auto resultFuture = MakeTask(&A::Func, A{}, 33, "bbb"); 
             ^^^^^ 
相關問題