[英]C++11 Capture Member Variable in Lambda
我有一個成員變量定義為:
HWND WindowHandle。
我正在嘗試捕獲變量並在Lambda中分配它。 所以編譯器給了我一個警告,並建議我捕獲“這個”。 我做了,但現在Handle只在Lambda中有效:S換句話說,它在Lambda之外是NULL。
class Foo
{
private:
HWND WindowHandle;
public:
Foo();
void MakeWindow(.......);
HWND GetWindowHandle() {return WindowHandle;};
};
Foo::Foo(){}
Foo::MakeWindow(.......)
{
Thread = std::thread([ClassName, Title, Width, Height, this]{
WindowHandle = CreateWindowEx(0, ClassName.c_str(), Title.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, 0, 0, GetModuleHandle(NULL), 0);
if(WindowHandle)
{
ShowWindow(WindowHandle, SW_SHOWDEFAULT);
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
}
});
}
int main()
{
Foo F;
F.MakeWindow(........);
std::cout<<std::boolalpha<<(F.GetWindowHandle() == NULL); //writes true.
}
以上創建窗口完美! 它只是Handle為null。 如何從Lambda中獲取Handle到我的班級成員?
那是因為你的代碼有競爭條件。 當你檢查main()中的值時,線程還沒有運行,所以WindowHandle仍然是NULL。
除非你還沒有真正啟動線程。 在這種情況下,由於線程尚未執行,因此WindowHandle仍為NULL。
無論如何,您需要在具有互斥鎖的線程之間同步對WindowHandle的訪問。
您只能捕獲局部變量,即在創建lambda的函數中聲明的內容或其參數之一。 在訪問成員x
時的成員函數中,實際上是訪問this->x
, this
是指向傳遞給成員函數的對象的隱式指針。 因此,lambda將捕獲this
而不是x
。 要捕獲成員,您需要創建一個包含它的局部變量,然后捕獲此變量,例如:
auto&& tmpWindowHandle = this->WindowHandle; // ... or just WindowHandle
...然后你將在lambda函數中捕獲tmpWindowHandle
。
由於你的lambda函數沒有顯示任何同步,你的GetWindowHandle()
似乎也沒有任何同步,你的調用線程可能會在你被線程設置之前訪問WindowHandle
成員:你需要某種形式的同步,它可以是一個join()
或某種形式的互斥或條件變量,然后才能調用其他一些線程使用WindowHandle
。 整體設置看起來像是std::future<...>
的良好應用:它旨在可能同時運行一個函數然后阻塞,直到實際訪問結果時需要結果。
您正在不同的線程上分配WindowHandle
。 所以可能發生的事情是你的新線程還沒有啟動,你正在檢查WindowHandle
是否已經改變。 此外,您應該使用某些互斥鎖或其他構造來保護對WindowHandle
訪問,否則您將遇到競爭條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.