2017-10-04 49 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 

参考:

相关问题