问题陈述 - tl;博士
将数字添加到矢量,然后输出
详情
我的目的是创建一个包含Foo
的类std::vector<int>
,我可以用线程安全的方式填充它。我创建了一个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;
};
然后我创建了一个自由函数,我可以用来创建一个线程,而不知道Foo
的内部。
void Func(Foo& foo, int t)
{
for (int i = 0; i < t; i++)
{
foo.AddValue(i);
}
}
我的目的是将以下值添加到向量中(由于线程时间的原因,它们以任何顺序结束)
{3, 2, 2, 1, 1, 1, 0, 0, 0, 0}
这是一个快速测试,看看它是否有效。
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();
}
问题
上面的代码won't compile
这是错误消息
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...>)
^
我不太明白错误信息。我没有正确地将线程添加到向量threads
吗?
答案 0 :(得分:7)
您必须将foo
包裹在std::ref
中。如果没有该包装器,线程不允许通过引用传递内容。