2017-10-04 45 views
2

我想在使用std::thread調用的函數中使用對抽象類(A)的引用作爲參數類型。 這似乎是不可能的,因爲編譯器試圖編譯:std::tuple<A>,甚至在我的代碼中,只有參考類型A被用作參數(從來沒有作爲值類型)。在Visual Studio的2017年對抽象類的引用無法傳遞給線程函數?

#include <cstdlib> 
#include <thread> 

class A { 
public: 
    virtual void a() = 0; 
}; 

class B : public A { 
public: 
    virtual void a() { 
    } 
}; 

class C { 
public: 
    C(A& aRef) { 
    thread = std::thread(&C::doSomething, this, aRef); 
    } 
private: 
    void doSomething(A& aRef) { 

    } 
    std::thread thread; 
}; 

int main(int argc, char* argv[]) { 
    B b; 
    C c(b); 
    return EXIT_SUCCESS; 
} 

將輸出:

error C2259: 'A': cannot instantiate abstract class 
tuple(278): note: see reference to class template instantiation 'std::tuple<A>' being compiled 
tuple(278): note: see reference to class template instantiation 'std::tuple<C *,A>' being compiled 
thread(49): note: see reference to class template instantiation 'std::tuple<void (__thiscall C::*)(A &),C *,A>' being compiled 
main.cpp(18): note: see reference to function template instantiation 'std::thread::thread<void(__thiscall C::*)(A &),C*const ,A&,void>(_Fn &&,C *const &&,A &)' being compiled 

爲什麼std::thread嘗試編譯std::tuple<A>?如果我直接從主線程調用C::doSomething,代碼編譯得很好。

有什麼我在這裏失蹤?

+2

你試過使用['std :: ref()'](http://en.cppreference.com/w/cpp/utility/functional/ref)嗎?否則,該參數可能會被複制。 – moooeeeep

+2

你需要用'std :: reference_wrapper'或lambda – user463035818

+2

'C(A&aRef):線程(&C :: doSomething,this,std :: ref(aRef)){}'來包裝引用。但更好的是:'C(A&aRef):thread([this,aRef] {doSomething(aRef);}){}' – rustyx

回答

1

當您將參考作爲參數傳遞給線程時,您需要將參考包裝在std::reference_wrapper中。

您可以使用std::ref()來做到這一點。

有在看看這個例子:

#include <thread> 
#include <utility> 
#include <iostream> 

struct A { 
    virtual void a() = 0; 
}; 

struct B : public A { 
    virtual void a() { std::cout << "Hello World\n"; } 
}; 

class C { 
    void doSomething(A& aRef) { aRef.a(); } 
    std::thread thread; 
public: 
    C(A& aRef) : thread(&C::doSomething, this, std::ref(aRef)) {} 
    // or alternatively using a lambda: 
    //C(A& aRef) : thread([&](){ doSomething(aRef); }) {} 
    void join() { thread.join(); } 
}; 

int main(int argc, char* argv[]) { 
    B b; 
    C c(b); 
    c.join(); 
} 

編譯和運行這樣的:

$ g++ ~/tt.cc -std=c++11 -pthread && ./a.out 
Hello World 

參考:

相關問題