| 網(wǎng)站首頁 | 關(guān)于我們 | 開發(fā)優(yōu)勢 | 產(chǎn)品展示 |
| 合作企業(yè) | 新聞動態(tài) | 聯(lián)系我們 | 電話聯(lián)系 |
文章作者:濟(jì)南軟件開發(fā) 時間:2016年12月20日
關(guān)于鏈?zhǔn)秸{(diào)用,比較典型的例子是c#中的linq,不過c#中的linq還只是一些特定函數(shù)的鏈?zhǔn)秸{(diào)用。c++中的鏈?zhǔn)秸{(diào)用更少見因為實現(xiàn)起來比較復(fù)雜。c++11支持了lamda和function,在一些延遲計算的場景下,這個鏈?zhǔn)秸{(diào)用的需求更強(qiáng)烈了。鏈?zhǔn)秸{(diào)用要實現(xiàn)的目是,將多個函數(shù)按照前一個的輸出作為下一個輸入串起來,然后再推遲到某個時刻計算。c++中,目前看到TBB和PPL中有這樣的用法。PPL中鏈?zhǔn)秸{(diào)用的例子:
復(fù)制代碼
int wmain()
{
auto t = create_task([]() -> int
{
return 0;
});
// Create a lambda that increments its input value.
auto increment = [](int n) { return n + 1; };
// Run a chain of continuations and print the result.
int result = t.then(increment).then(increment).then(increment).get();
wcout << result << endl;
}
/* Output:
3
*/
復(fù)制代碼
例子中先創(chuàng)建一個task對象,然后連續(xù)的調(diào)用then函數(shù),其實這個then中的lamda的形參可以是任意類型的,只要保證前一個函數(shù)的輸出為后一個的輸入就行。將這些task串起來之后,最后在需要的時候去計算結(jié)果,計算的過程是鏈?zhǔn)降?,從最開始的函數(shù)開始計算一直到最后一個得到最終結(jié)果。這個task和他的鏈?zhǔn)秸{(diào)用
過程是很有意思的。不過PPL中的鏈?zhǔn)秸{(diào)用有一點不太好,就是初始化的task不能有參數(shù),因為wait函數(shù)是不能接收參數(shù)的。經(jīng)過一番探索,我覺得用c++11我可以做一個差不多鏈?zhǔn)秸{(diào)用的task,還可以彌補(bǔ)前面所說PPL task不太好的地方,即可以接收參數(shù)。其實關(guān)于鏈?zhǔn)秸{(diào)用的實現(xiàn)我之前有博文做了介紹,有興趣的童孩點這里。不過我對之前的實現(xiàn)方式不太滿意,覺得還是PPL這種鏈?zhǔn)秸{(diào)用方式更好。好了,下面看看我是如何實現(xiàn)和ppl類似的,可以實現(xiàn)鏈?zhǔn)秸{(diào)用的task。
復(fù)制代碼
template<typename T>
class Task;
template<typename R, typename...Args>
class Task<R(Args...)>
{
public:
Task(std::function<R(Args...)> f) : m_fn(std::move(f)){}
template<typename... Args>
R Run(Args&&... args)
{
return m_fn(std::forward<Args>(args)...);
}
template<typename F>
auto Then(F& f)->Task<typename std::result_of<F(R)>::type(Args...)>
{
return Task<typename std::result_of<F(R)>::type(Args...)>([this, &f](Args&&... args){
return f(m_fn(std::forward<Args>(args)...)); });
}
private:
std::function<R(Args...)> m_fn;
};
復(fù)制代碼
測試代碼:
void TestTask()
{
Task<int(int)> task = [](int i){return i;};
auto result = task.then([](int a){return i+1;}).then([](int a){return i+2;}).then([](int a){return i+3;}).run(1);
//result 7
}
可以看到,我的Task調(diào)用方式和PPL一致,更棒的是還可以接收參數(shù)了。也許有人有點疑惑,鏈?zhǔn)秸{(diào)用這個東西真的有用嗎?至少目前看到PPL和TBB是這樣用的,而且他對我的開發(fā)來說非常有用,至于我對他的具體應(yīng)用暫且按下不表,后面就會知道我是如何用它了。
想要了解更多詳情歡迎來電咨詢18678812288
登陸網(wǎng)址:m.h6244.cn。
聯(lián)系人:王經(jīng)理。