2012-08-01 118 views
22

我試着編寫一個類成員,並行調用另一個類成員多次。在C++中的類成員上的類和std :: async

我寫了一個簡單的例子,甚至無法編譯這個問題。我在調用std :: async時做錯了什麼?我想這個問題會與我如何傳遞函數有關。

#include <vector> 
#include <future> 
using namespace std; 
class A 
{ 

int a,b; 
public: 
A(int i=1, int j=2){ a=i; b=j;} 

std::pair<int,int> do_rand_stf(int x,int y) 
{ 
    std::pair<int,int> ret(x+a,y+b); 
    return ret; 
} 

void run() 
{ 
    std::vector<std::future<std::pair<int,int>>> ran; 
    for(int i=0;i<2;i++) 
    { 
     for(int j=0;j<2;j++) 
     { 
      auto hand=async(launch::async,do_rand_stf,i,j); 
      ran.push_back(hand);  
     } 
    } 
    for(int i=0;i<ran.size();i++) 
    { 
     pair<int,int> ttt=ran[i].get(); 
     cout << ttt.first << ttt.second << endl; 
    } 
} 
}; 
int main() 
{ 
A a; 
a.run(); 
} 

編譯:(隱式this參數)

g++ -std=c++11 -pthread main.cpp 
+0

通'* this'作爲第三個參數爲'async'。 – Xeo 2012-08-01 11:44:09

+1

如果您在編譯或鏈接時遇到錯誤,在問題中包含這些錯誤,最好是逐字記錄將是一個好主意。 – 2012-08-01 11:44:50

+0

您不需要再使用pthread與C++ 11 :)這是C++ 11(線程)中最大的添加之一。如果異步啓動和顯式線程也存在於語言本身中,則async()是隱式線程。 – siddhusingh 2012-11-15 09:31:04

回答

38

do_rand_stf是一個非靜態成員函數,因此不能沒有一個類的實例被稱爲幸運的是,std::async處理其參數,如std::bind,和bind反過來可以使用std::mem_fn將成員函數指針變成一個函數,該函數需要明確的this參數,因此您只需將this傳遞給std::async調用並傳遞do_rand_stf時使用的有效成員函數指針語法:

auto hand=async(launch::async,&A::do_rand_stf,this,i,j); 

有在代碼中的其他問題,雖然。首先,您使用std::coutstd::endl而不使用#include ing <iostream>。更嚴重的是,std::future是不可複製的,只能移動,因此您不能使用std::move命名的對象10。或者,只要傳遞async結果push_back直接:

​​
+0

謝謝,解決了所有問題。 :) – UldisK 2012-08-01 12:08:36

+0

很好的解釋@JohannesD – siddhusingh 2012-11-15 08:20:54

+0

你救了我的命。謝謝 – Porizm 2016-05-10 19:54:15

1

您可以將this指針傳遞給一個新的線程:

async([this]() 
{ 
    Function(this); 
}); 
+0

也許我錯過了一些東西,但是'this'和'that'有什麼不同呢?內線程的'this'與外線程的'this'相同,除了不應該有內線程'this'',除非被捕獲?聽起來更像是JavaScript技巧...... – 2017-05-29 08:26:36

+1

'this_thread :: get_id()'是一種查看線程ID差異的方法,而不是'this'。如果你完全不捕獲它,那麼lambda表達式將不可用。像這裏 - http://ideone.com/uWNs4p - 你需要明確地捕獲this。如果你這樣做,它與lambda之外沒有什麼不同 - http://ideone.com/YuPKf9 – 2017-05-30 08:07:09

+1

@ MichaelKrelin-hacker你看起來是正確的,至少用gcc:http://ideone.com/G9icfv我用的是視覺工作室;它很有可能與此不同。 – Andrew 2017-05-31 13:57:53