2016-01-11 31 views
14

在Boost.Asio的C++ 11分的例子有段like the following爲什麼要在lambdas中捕獲這個以及共享指針?

void do_read() 
{ 
    auto self(shared_from_this()); 
    socket_.async_read_some(boost::asio::buffer(data_, max_length), 
     [this, self](boost::system::error_code ec, std::size_t length) 
     { 
     if (!ec) 
     { 
      do_write(length); 
     } 
     }); 
} 

我理解爲什麼需要self指針以保持類活着(見this question),但我不明白爲什麼this指針捕獲。僅僅是爲了讓作者可以寫do_write(length)而不是self->do_write(length)還是有其他原因?

+1

一句話:方便。 – sehe

回答

5

如果不捕獲this,則不能從lambda內調用該類的方法(例如,do_write)。或者訪問成員變量。當然,你可以改爲寫self->do_write(),但它既不那麼優雅,也可能較慢(因爲涉及shared_ptr)。

+1

只是爲了擴大速度問題:從[這個問題]的答案(http://stackoverflow.com/questions/22295665/how-much-is-the-overhead-of-smart-pointers-compared-to-normal-指針在C)似乎表明,在舊的/壞的編譯器解引用一個智能指針可能會更慢,以解引用原始指針,但現代編譯器應該幾乎沒有懲罰。 – dshepherd

+0

@dshepherd:足夠公平,但在禁用優化(例如調試模式)時可能仍然較慢。 –

+0

@shep我不知道:這是一個容易確定對象的const指針。共享ptr由存儲在objecr中的弱ptr構造而成,第一次從對象創建共享ptr時進行初始化。我無法想象有沒有優化器遇到問題的情況,更不用說由此共享的事實可以爲空! – Yakk

2

放棄的答案有絕對錯!你不應該兩個都通過!這裏是你應該怎麼做,根據你的代碼,沒有通過this

void do_read() 
{ 
    auto self(shared_from_this()); 
    socket_.async_read_some(boost::asio::buffer(data_, max_length), 
     [self](boost::system::error_code ec, std::size_t length) 
     { 
     if (!ec) 
     { 
      self->do_write(length); 
     } 
     }); 
} 

而實際上,你應該使用std::bind,不是這個lambda表達式。這會讓你的代碼更加緊湊。

+1

紫羅蘭長頸鹿的答案似乎對我完全有意義。你能否詳細說明它是如何錯誤的,以及爲什麼你的更好? – Quentin

+0

@Quentin引用「如果沒有捕捉到,你不能從lambda內調用類的方法」。這純粹是錯誤的。 「自我」可以做到「這個」所做的事情。另外假設'shared_from_this'較慢(儘管他說「可能」,這是一個無用的,防禦性的,流暢的答案)是錯誤的。 'operator->'不做任何檢查,所以最少的優化會殺死任何性能差異。這個答案沒有提供任何有用的信息,而是基於假設和概括的錯誤信息。對不起,我很吃驚,但我很驚訝。 –

+0

閱讀文檔後,確實不應該有任何性能影響。但是,您確實會失去直接成員訪問權限(即不存在'this->'和'self->')。 – Quentin

相關問題