将std :: shared_ptr传递给std :: thread的函数对象

时间:2016-11-09 03:55:15

标签: c++ multithreading c++11 shared-ptr functor

只要我的线程有,就需要运行这个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;我在这段代码中做了什么?!

3 个答案:

答案 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

Demo

答案 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>。当线程结束时,智能指针将被删除。

缺点:消除了拥有函子的好处,因为您必须指定成员函数。