我目前正在C ++中的一个项目中,其中有一个存储在向量中的结构体列表,这些结构体与它们有很多关联。为了加快处理速度,我选择将程序拆分到多个线程中,而我选择这样做的惰性方法是在标准库向量的每个结构上添加互斥量。这样,我可以让多个线程在数组上进行迭代,并通过调用mutex.try_lock()并完成与该元素的关联处理,或移至下一个打开的元素,从而基本上获取各个元素的所有权。
在开始之前,请注意以下实际上是有效的。
#include <mutex>
#include <vector>
struct foo {
int a;
std::mutex b;
};
void working_demo () {
// assign by initializer list
foo f = {.a = 1};
}
int main () {
working_demo();
}
因此,我打算以与上面非常相似的方式填充我的标准向量,并且不起作用。
#include <mutex>
#include <vector>
struct foo {
int a;
std::mutex b;
};
void broken_demo () {
std::vector<foo> bar;
// assign by initializer list
bar.push_back({.a = 1});
}
int main () {
broken_demo();
}
编译器错误:
clang++ -std=c++11 -Wall -Wextra -Wfatal-errors -pedantic -I./ -c -o demo.o demo.cpp
demo.cpp:13:20: warning: designated initializers are a C99 feature [-Wc99-extensions]
bar.push_back({.a = 1});
^~~~~~
In file included from demo.cpp:1:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/mutex:38:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/tuple:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/array:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/stdexcept:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/string:41:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/allocator.h:46:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/x86_64-pc-linux-gnu/bits/c++allocator.h:33:
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/ext/new_allocator.h:146:8: fatal error: call to implicitly-deleted copy constructor of 'foo'
_Up(std::forward<_Args>(__args)...)))
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/alloc_traits.h:483:24: note: in instantiation of exception specification for
'construct<foo,foo>' requested here
noexcept(noexcept(__a.construct(__p,std::forward<_Args>(__args)...)))
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:115:21: note: in instantiation of exception specification for 'construct<foo,foo>'
requested here
_Alloc_traits::construct(this->_M_impl,this->_M_impl._M_finish,^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_vector.h:1201:9: note: in instantiation of function template specialization
'std::vector<foo,std::allocator<foo> >::emplace_back<foo>' requested here
{ emplace_back(std::move(__x)); }
^
demo.cpp:13:9: note: in instantiation of member function 'std::vector<foo,std::allocator<foo> >::push_back' requested here
bar.push_back({.a = 1});
^
demo.cpp:6:16: note: copy constructor of 'foo' is implicitly deleted because field 'b' has a deleted copy constructor
std::mutex b;
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/std_mutex.h:94:5: note: 'mutex' has been explicitly marked deleted here
mutex(const mutex&) = delete;
^
我可以肯定地说这是行不通的,原因是该结构正在尝试为互斥量调用复制构造函数,而互斥量实际上没有复制构造函数。我明确地不想这样做。
我最初的想法是,为了确保它甚至不尝试调用互斥量的副本构造函数,我可以为我的类创建自己的构造函数,并且基本上显式地省略了互斥量的复制。这种方法看起来像这样-但是它也不起作用。
#include <mutex>
#include <vector>
struct foo {
foo (int A): a(A) {;}
int a;
std::mutex b;
};
void broken_demo () {
std::vector<foo> bar;
// assign by initializer list
bar.emplace_back(1);
}
int main () {
broken_demo();
}
编译器错误:
clang++ -std=c++11 -Wall -Wextra -Wfatal-errors -pedantic -I./ -c -o demo.o demo.cpp
In file included from demo.cpp:2:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/vector:65:
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_construct.h:75:38: fatal error: call to implicitly-deleted copy constructor of 'foo'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:83:8: note: in instantiation of function template specialization
'std::_Construct<foo,foo>' requested here
std::_Construct(std::__addressof(*__cur),*__first);
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:134:2: note: in instantiation of function template specialization
'std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<foo *>,foo *>' requested here
__uninit_copy(__first,__last,__result);
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:289:19: note: in instantiation of function template specialization
'std::uninitialized_copy<std::move_iterator<foo *>,foo *>' requested here
{ return std::uninitialized_copy(__first,__result); }
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:310:19: note: in instantiation of function template specialization
'std::__uninitialized_copy_a<std::move_iterator<foo *>,foo *,foo>' requested here
return std::__uninitialized_copy_a
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:473:10: note: in instantiation of function template specialization
'std::__uninitialized_move_if_noexcept_a<foo *,std::allocator<foo> >' requested here
= std::__uninitialized_move_if_noexcept_a
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:121:4: note: in instantiation of function template specialization 'std::vector<foo,std::allocator<foo> >::_M_realloc_insert<int>' requested here
_M_realloc_insert(end(),std::forward<_Args>(__args)...);
^
demo.cpp:15:9: note: in instantiation of function template specialization 'std::vector<foo,std::allocator<foo> >::emplace_back<int>' requested here
bar.emplace_back(1);
^
demo.cpp:8:16: note: copy constructor of 'foo' is implicitly deleted because field 'b' has a deleted copy constructor
std::mutex b;
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/std_mutex.h:94:5: note: 'mutex' has been explicitly marked deleted here
mutex(const mutex&) = delete;
^
1 error generated.
对此有任何想法吗?我希望使代码相对简单,但是我不确定如何使标准向量发挥作用,或者至少正确使用它。