[如果结构包含互斥量,将初始化列表推到标准向量上的C ++问题

问题描述 投票:2回答:2

我目前正在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, __last, __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 *, 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.

对此有任何想法吗?我希望使代码相对简单,但是我不确定如何使标准向量发挥作用,或者至少正确使用它。

我目前正在C ++中的一个项目中,其中有一个存储在向量中的结构体列表,这些结构体与它们有很多关联。为了加快处理速度,我选择拆分...

c++ mutex clang++ initializer-list deleted-functions
2个回答
1
投票
问题是foo在您的代码实例中按值传递。因此,当您将某些内容放入向量中时,需要创建一个副本。避免这种情况的一种简单方法是将指向foo的指针放入向量中。您可以将指针包装到某种引用计数机制中,从而不必跟踪释放对象的情况。

0
投票
看了其中一种解决方案后,我认为实际上该解决方案最适合我要的解决方案。如果没有上述有用的建议,我将无法解决。
© www.soinside.com 2019 - 2024. All rights reserved.