2013-03-15 124 views
13

我剛剛開始使用C++ 11線程,我一直在努力(可能很愚蠢)的錯誤。 這是我的示例程序:C++ 11線程初始化與成員函數編譯錯誤

#include <iostream> 
#include <thread> 
#include <future> 
using namespace std; 

class A { 
public: 
    A() { 
    cout << "A constructor\n"; 
    } 

    void foo() { 
    cout << "I'm foo() and I greet you.\n"; 
    } 

    static void foo2() { 
    cout << "I'm foo2() and I am static!\n"; 
    } 

    void operator()() { 
    cout << "I'm the operator(). Hi there!\n"; 
    } 
}; 

void hello1() { 
    cout << "Hello from outside class A\n"; 
} 

int main() { 
    A obj; 
    thread t1(hello1); // it works 
    thread t2(A::foo2); // it works 
    thread t3(obj.foo); // error 
    thread t4(obj);  // it works 

    t1.join(); 
    t2.join(); 
    t3.join(); 
    t4.join(); 
    return 0; 
} 

是否有可能從一個純粹的成員函數啓動一個線程?如果不是,我怎麼能包裝我的foo函數從對象obj能夠創建這樣的線程? 在此先感謝!

這是編譯錯誤:

thread_test.cpp: In function ‘int main()’: thread_test.cpp:32:22: error: no matching function for call to ‘std::thread::thread()’

thread_test.cpp:32:22: note: candidates are:

/usr/include/c++/4.6/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(), _Args = {}]

/usr/include/c++/4.6/thread:133:7: note: no known conversion for argument 1 from ‘’ to ‘void (A::*&&)()’

/usr/include/c++/4.6/thread:128:5: note: std::thread::thread(std::thread&&)

/usr/include/c++/4.6/thread:128:5: note: no known conversion for argument 1 from ‘’ to ‘std::thread&&’

/usr/include/c++/4.6/thread:124:5: note: std::thread::thread()

/usr/include/c++/4.6/thread:124:5: note: candidate expects 0 arguments, 1 provided

+3

嘗試一個簡單的lambda:'[&](){obj.foo();}'。 [Full code here](http://liveworkspace.org/code/4Fh1lL$1)。 – BoBTFish 2013-03-15 14:10:56

+0

謝謝Angew,我一定會在將來的帖子中改變標籤。 – Rob013 2013-03-15 14:30:26

回答

20

你需要調用對象採取任何參數,因此

thread t3(&A::foo, &obj); 

應該做的伎倆。這具有創建可調用實體的效果,其在obj上調用A::foo

原因是A的非靜態成員函數採用類型的隱式第一個參數(可能是cv限定的)A*。當您致電obj.foo()時,您實際上呼叫A::foo(&obj)。一旦你知道了,上面的咒語是非常有道理的。

+0

完美的謝謝!我很抱歉轉貼了一個現有問題,我可能錯過了正確的標籤。順便說一句,現在它的作品! – Rob013 2013-03-15 14:29:06

+2

@ Rob013很高興幫助。其實,我剛剛意識到這在複製中沒有很好的解釋。 – juanchopanza 2013-03-15 14:42:41

+0

@juanchopanza我明白任何成員函數(非靜態)都會採用該類型的隱式第一個參數(該實例的此指針)。但是,如果我將對象作爲參數傳遞(就像你在線程中分配它的方式)來調用任何普通成員函數(例如A :: foo(&obj);)),爲什麼它不起作用?請告訴我更多關於這個的信息。這個概念的任何鏈接將會很好。謝謝.. – 2016-04-12 09:06:51