2014-01-25 21 views
4

我試圖模仿的std :: thread構造函數的功能:如何可變參數模板PARAMS綁定功能

template< class Function, class... Args > 
explicit thread(Function&& f, Args&&... args); 

我試着調試器步進,看看它是如何工作,但我想不出它出。

如何創建和存儲線程的構造函數的綁定類型呢?

像這樣的東西(語法錯誤的可能):

​​

使用示例:

int test(int i) {return i;} 

int main(){ 
myClass my(test, 5); 
my.evaluate(); 
} 

請注意,我不關心,如果somehowBind功能將忽略返回類型,即其返回類型可以像std :: function一樣。 我想要做的就是了解如何將class... Args綁定到給定函數f,以便在調用somehowBind之後,它將像std :: bind那樣操作。 爲了澄清我的觀點,你可以想想我想實現如下:

thread t(test, 5); // unlike the usual std:::thread, this one is created in suspended mode therefore I need somehow to bind `f` with `5` and store it 
t.start(); // now t is executed 

它還挺提醒C#和Java線程,他們不能施工後立即執行。

+1

我認爲你需要解釋一下更正是你想要達到的目標。 – tumdum

+0

在包裝代碼的各個層次深處,會有一個'std :: tuple'存儲可變參數,指針或對它們的引用。正如Tomasz所說,給出一些關於你的包裝代碼應該是什麼樣的細節。 – bobah

+0

你在尋找'std :: function'嗎? 'class myClass {std :: function m; public:template myClass(F && f,Args && ... args):m(std :: bind(std :: forward (f),std :: forward (args)。 ();} {} void evaluate(){m();}};' – dyp

回答

4

對於初學者來說,一些參數綁定到一個函數使用std::bind你的simpy做:

// Some function. 
void printValues(int x, double y) { 
    std::cout << x << " " << y << std::endl; 
} 

auto func = std::bind(printValues, 5, 2.0); // Bind params and return functor. 
func(); // Evaluate function call (returns void in this case). 

接下來,存儲一個仿函數及其一類的參數,你不關心的返回值時評價然後只需使用lambda表達式來包裝std::bind表達式(拉姆達用於刪除的返回值):

struct Foo { 
    template <typename Function, typename... Args> 
    Foo(Function&& func, Args&&... args) { 
     auto f = std::bind(std::forward<Function>(func), std::forward<Args>(args)...); 
     func_ = [f] { f(); }; 
     // func_ = [f{std::move(f)}] { f(); }; // In C++14 you can move capture. 
    } 
    void evaluate() { func_(); } 
    std::function<void()> func_; 
}; 

Also see this live example

如果你正在尋找存儲可變參數包然後看看這個答案:How to store variadic template arguments?

+1

正如我在對OP的評論中所說的那樣,'bind'仿函數的返回值可以轉換爲void。你不需要用lambda包裝它。 [現場示例](http:// coliru。stacked-crooked.com/a/65fe57cef319a026) – dyp

+0

@dyp但我認爲'bind'仿函數的返回值是作爲參數傳遞給它的可調參數的返回值?例如。 'int'不能隱式轉換爲'void'?我只是想要得到這個。 – Snps

+0

嗯現在它變得有趣。看起來類型並不隱含,但只能明確地轉換爲「void」。 'std :: function'的要求似乎要求*隱式*通過*'INVOKE * *轉換,但是'std :: function :: operator()'包含'void'返回類型的特殊情況。 libstdC++的'std :: function'實現包含一個特殊情況,用於檢查傳遞的實體是否可調用,即如果目標返回類型爲'void',則它接受可調用的任何返回類型。即這是標準中的錯誤(可以很容易地修復)或者libstdC++擴展。 – dyp