只要我的线程有,就需要运行这个Functor,所以我已经创建了一个shared_ptr并试图将它传递给std :: thread。我在这里复制了代码和错误列表。
struct Functor
{
std::string greeting;
explicit Functor(std::string _greeting="Hello!"): greeting { _greeting } {}
void operator()()
{
std::cout << greeting << "\n";
}
};
auto main() ->int
{
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t(&fp);
t.join();
return 0;
}
错误列表:
Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)' std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
Error C2672 'std::invoke': no matching overloaded function found std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
我是c ++ 11和并发新手。请帮我理解以下内容
1&gt; std :: thread总是在按值传递时调用对象内的operator()吗?如果是这样,为什么定义它。
2&gt;如果线程确实给予线程的资源保持不变?
3&gt;是这里写的 Functor ,一个函数对象?
4&gt;我在这段代码中做了什么?!
答案 0 :(得分:0)
1&gt; std :: thread总是调用对象内的operator() 什么时候通过值?如果是这样,为什么定义它。
std::thread
调用std::invoke
。从cppreference,如果第一个参数既不是pointer to member function
也不是pointer to data member
;它被视为一个功能对象。
因此,将调用fp()。
INVOKE(f,t1,t2,...,tN)相当于f(t1,t2,...,tN)(即 是,f是一个FunctionObject)
所以你基本上可以做std::thread t{*fp}
2&gt;如何确保给予线程的资源保持不变 作为线程吗?
您可以shared_ptr
提供共享对象的所有权。或者您可以通过确保传递的资源在范围内来手动执行此操作。里程各不相同。
3&gt;是这里写的Functor,一个函数对象?
是。 FunctionObject类型是可以在函数调用运算符左侧使用的对象类型。但是fp
不是。但*fp
是。
4&gt;我在这段代码中做了什么?!
您可以通过使用参数Functor::operator()
显式传递fp.get()
来使其工作。当然,一个简单的方法就是通过*fp
答案 1 :(得分:0)
operator()
不可调用 - 即使在Functor
的情况下,它也不会实现shared_ptr
。
这里int main() {
Functor f;
std::thread t(std::ref(f));
t.join();
return 0;
}
的目的是什么?为什么不简单
Functor
如果出于某种原因,您坚持让shared_ptr
实例由int main() {
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t([fp]() { (*fp)(); });
t.join();
return 0;
}
管理,请按以下方式进行:
{{1}}
答案 2 :(得分:0)
您仍然可以使用以下语法让 std::thread
拥有您的智能指针:
std::shared_ptr<Functor> f = std::make_shared<Functor>();
std::thread thread (&Functor::operator(), f);
thread.detach();
如果第一个参数是成员函数指针,那么第二个参数应该是指向类实例的引用或指针,并且接受 std::shared_ptr<Functor>
。当线程结束时,智能指针将被删除。
缺点:消除了拥有函子的好处,因为您必须指定成员函数。