C++ 将函数和参数传递给线程

C++ 将函数和参数传递给线程,c++,multithreading,c++11,C++,Multithreading,C++11,问题陈述-tl;dr 将数字添加到向量,然后输出它们 详细信息 我的意图是创建一个类Foo,它包含一个std::vector,我可以用线程安全的方式填充它。我创建了一个AddValue方法,允许向该向量添加值,同时牢记线程安全性 std::mutex mt; class Foo { public: void AddValue(int i) { std::lock_guard<std::mutex> lg{ mt }; values.pu

问题陈述-tl;dr
将数字添加到向量,然后输出它们

详细信息

我的意图是创建一个类
Foo
,它包含一个
std::vector
,我可以用线程安全的方式填充它。我创建了一个
AddValue
方法,允许向该向量添加值,同时牢记线程安全性

std::mutex mt;
class Foo
{
public:
    void AddValue(int i)
    {
        std::lock_guard<std::mutex> lg{ mt };
        values.push_back(i);
    }

    void PrintValues() const
    {
        for (int i : values)
        {
            std::cout << i << " ";
        }
    }

private:
    std::vector<int> values;
};
我的意图是将以下值添加到向量中(由于线程计时,它们以任何顺序结束)

下面是一个快速测试,看看这是否有效

int main()
{
    Foo foo;
    std::vector<std::thread> threads;
    for (int i = 1; i < 5; ++i)
    {
        threads.emplace_back(Func, foo, i);
    }

    std::for_each(begin(threads), end(threads), [](std::thread& t){ t.join(); });

    foo.PrintValues();
}
intmain()
{
富富,;
向量线程;
对于(int i=1;i<5;++i)
{
线程。向后放置(Func、foo、i);
}
std::for_each(开始(线程)、结束(线程),[](std::thread&t){t.join();});
foo.PrintValues();
}
问题
上述代码

这是错误消息

In file included from /usr/include/c++/4.9/mutex:42:0,
                 from 3:
/usr/include/c++/4.9/functional: In instantiation of 'struct std::_Bind_simple<void (*(Foo, int))(Foo&, int)>':
/usr/include/c++/4.9/thread:140:47:   required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(Foo&, int); _Args = {Foo&, int&}]'
/usr/include/c++/4.9/ext/new_allocator.h:120:4:   required from 'void __gnu_cxx::new_allocator< <template-parameter-1-1> >::construct(_Up*, _Args&& ...) [with _Up = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Tp = std::thread]'
/usr/include/c++/4.9/bits/alloc_traits.h:253:4:   required from 'static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Alloc = std::allocator<std::thread>; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]'
/usr/include/c++/4.9/bits/alloc_traits.h:399:57:   required from 'static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Alloc = std::allocator<std::thread>; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]'
/usr/include/c++/4.9/bits/vector.tcc:97:40:   required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {void (&)(Foo&, int), Foo&, int&}; _Tp = std::thread; _Alloc = std::allocator<std::thread>]'
44:42:   required from here
/usr/include/c++/4.9/functional:1665:61: error: no type named 'type' in 'class std::result_of<void (*(Foo, int))(Foo&, int)>'
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/4.9/functional:1695:9: error: no type named 'type' in 'class std::result_of<void (*(Foo, int))(Foo&, int)>'
         _M_invoke(_Index_tuple<_Indices...>)
         ^
在/usr/include/c++/4.9/mutex:42:0中包含的文件中,
从3开始:
/usr/include/c++/4.9/functional:在“struct std::_Bind_simple”的实例化中:
/usr/include/c++/4.9/thread:140:47:从'std::thread::thread(_Callable&&,_Args&&&…[with _Callable=void(&)(Foo&,int);_Args={Foo&,int&}]中需要
/usr/include/c++/4.9/ext/new_allocator.h:120:4:void\u gnu\u cxx::new_allocator中的必填项::construct(_Up*,_Args&&…[with _Up=std::thread;_Args={void(&)(Foo&,int),Foo&,int&};_Tp=std::thread]'
/usr/include/c++/4.9/bits/alloc_traits.h:253:4:static std::_requirestd::allocator_traits::_S_构造(_alloc&,_Tp*,_Args&…[带_Tp=std::thread;_Args={void(&)(Foo&,int),Foo&,int&};_alloc=std::alloc::allocator;std:_Require=void])
/usr/include/c++/4.9/bits/alloc_traits.h:399:57:static decltype(__a,__p,(forward)(std::allocator_traits::construct::__args))std::allocator_traits::construct(_-alloc,_-Tp*,_-args&…[带_-Tp=std::thread;_-args={-void(&)(Foo&,int),Foo&,int&),int&,int&;)allocator&;)std::allocator&;)构造()decu::allocator&(_a,_p,(forward)(std::allocator_traits::construct::_args))=]'
/usr/include/c++/4.9/bits/vector.tcc:97:40:void std::vector::emplace_back(_Args&&…)[with _Args={void(&)(Foo&,int),Foo&,int&};_Tp=std::thread;_Alloc=std::Alloc::allocator]中的必需项
44:42:从这里开始需要
/usr/include/c++/4.9/functional:1665:61:错误:在'class std::result_of'中没有名为'type'的类型
typedef typename result_of::type result_type;
^
/usr/include/c++/4.9/functional:1695:9:错误:在“class std::result_of”中没有名为“type”的类型
_M_invoke(_Index_tuple)
^

我不太理解这个错误消息。我没有正确地将线程添加到向量
threads
中吗?

您必须将
foo
包装在
std::ref
中。没有该包装器,线程不允许通过引用传递内容。

您可能必须将
foo
包装在
std::ref
中ds不允许在没有包装器的情况下通过引用传递内容。这是一条非常模糊的错误消息。@Carcigenicate你完全正确,解决了它!很好。我喜欢在黑暗中拍摄。我的经验法则是,如果正在线程化的函数有一个带有
&
的参数,那么我应该有一个相应的
std::ref()
int main()
{
    Foo foo;
    std::vector<std::thread> threads;
    for (int i = 1; i < 5; ++i)
    {
        threads.emplace_back(Func, foo, i);
    }

    std::for_each(begin(threads), end(threads), [](std::thread& t){ t.join(); });

    foo.PrintValues();
}
In file included from /usr/include/c++/4.9/mutex:42:0,
                 from 3:
/usr/include/c++/4.9/functional: In instantiation of 'struct std::_Bind_simple<void (*(Foo, int))(Foo&, int)>':
/usr/include/c++/4.9/thread:140:47:   required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(Foo&, int); _Args = {Foo&, int&}]'
/usr/include/c++/4.9/ext/new_allocator.h:120:4:   required from 'void __gnu_cxx::new_allocator< <template-parameter-1-1> >::construct(_Up*, _Args&& ...) [with _Up = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Tp = std::thread]'
/usr/include/c++/4.9/bits/alloc_traits.h:253:4:   required from 'static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Alloc = std::allocator<std::thread>; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]'
/usr/include/c++/4.9/bits/alloc_traits.h:399:57:   required from 'static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {void (&)(Foo&, int), Foo&, int&}; _Alloc = std::allocator<std::thread>; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]'
/usr/include/c++/4.9/bits/vector.tcc:97:40:   required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {void (&)(Foo&, int), Foo&, int&}; _Tp = std::thread; _Alloc = std::allocator<std::thread>]'
44:42:   required from here
/usr/include/c++/4.9/functional:1665:61: error: no type named 'type' in 'class std::result_of<void (*(Foo, int))(Foo&, int)>'
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/4.9/functional:1695:9: error: no type named 'type' in 'class std::result_of<void (*(Foo, int))(Foo&, int)>'
         _M_invoke(_Index_tuple<_Indices...>)
         ^