首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何调整std::vector<std::queue<std::unique_ptr<int>>>?的大小

如何调整std::vector<std::queue<std::unique_ptr<int>>>?的大小
EN

Stack Overflow用户
提问于 2020-12-04 09:00:02
回答 2查看 350关注 0票数 4

我想做以下几件事:

代码语言:javascript
复制
#include <memory>
#include <vector>
#include <queue>

int main() {
    std::vector<std::queue<std::unique_ptr<int>>> v;
    v.resize(10);
}

但是我和GCC一起得到了10.2:

代码语言:javascript
复制
$ g++ test.cpp -o test
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/memory:66,
                from test.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<int>, const std::unique_ptr<int>&, const std::unique_ptr<int>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<int>, std::unique_ptr<int>&, std::unique_ptr<int>*>]':
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<int>, const std::unique_ptr<int>&, const std::unique_ptr<int>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<int>, std::unique_ptr<int>&, std::unique_ptr<int>*>; _Tp = std::unique_ptr<int>]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_deque.h:896:36:   required from 'std::deque<_Tp, _Alloc>::deque(const std::deque<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<int>; _Alloc = std::allocator<std::unique_ptr<int> >]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_queue.h:96:11:   required from 'void std::_Construct(_Tp*, _Args&& ...) [with _Tp = std::queue<std::unique_ptr<int> >; _Args = {const std::queue<std::unique_ptr<int, std::default_delete<int> >, std::deque<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > > >&}]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:91:18:   required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const std::queue<std::unique_ptr<int> >*; _ForwardIterator = std::queue<std::unique_ptr<int> >*; bool _TrivialValueTypes = false]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:150:15:   required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const std::queue<std::unique_ptr<int> >*; _ForwardIterator = std::queue<std::unique_ptr<int> >*]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const std::queue<std::unique_ptr<int> >*; _ForwardIterator = std::queue<std::unique_ptr<int> >*; _Tp = std::queue<std::unique_ptr<int> >]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:347:2:   required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = std::queue<std::unique_ptr<int> >*; _ForwardIterator = std::queue<std::unique_ptr<int> >*; _Allocator = std::allocator<std::queue<std::unique_ptr<int> > >]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/vector.tcc:659:48:   required from 'void std::vector<_Tp, _Alloc>::_M_default_append(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::queue<std::unique_ptr<int> >; _Alloc = std::allocator<std::queue<std::unique_ptr<int> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int]'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_vector.h:940:4:   required from 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::queue<std::unique_ptr<int> >; _Alloc = std::allocator<std::queue<std::unique_ptr<int> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int]'
test.cpp:7:16:   required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:137:72: error: static assertion failed: result type must be constructible from value type of input range
137 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
    |                                                                        ^~~~~

同样适用于clang++11

代码语言:javascript
复制
$ clang++-11 test.cpp -o test
In file included from test.cpp:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/memory:66:
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:137:7: error: static_assert failed due to requirement 'is_constructible<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &>::value' "result type must be constructible from value type of input range"
    static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &, const std::unique_ptr<int, std::default_delete<int>> *>, std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, std::unique_ptr<int, std::default_delete<int>> &, std::unique_ptr<int, std::default_delete<int>> *>>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_deque.h:896:14: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &, const std::unique_ptr<int, std::default_delete<int>> *>, std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, std::unique_ptr<int, std::default_delete<int>> &, std::unique_ptr<int, std::default_delete<int>> *>, std::unique_ptr<int, std::default_delete<int>>>' requested here
    { std::__uninitialized_copy_a(__x.begin(), __x.end(),
            ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_queue.h:96:11: note: in instantiation of member function 'std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>::deque' requested here
    class queue
        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:91:8: note: in instantiation of function template specialization 'std::_Construct<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>, const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> &>' requested here
                std::_Construct(std::__addressof(*__cur), *__first);
                    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:150:2: note: in instantiation of function template specialization 'std::__uninitialized_copy<false>::__uninit_copy<const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *>' requested here
        __uninit_copy(__first, __last, __result);
        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:346:19: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>' requested here
    return std::__uninitialized_copy_a
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/vector.tcc:659:14: note: in instantiation of function template specialization 'std::__uninitialized_move_if_noexcept_a<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>' requested here
                    std::__uninitialized_move_if_noexcept_a(
                        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_vector.h:940:4: note: in instantiation of member function 'std::vector<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>::_M_default_append' requested here
        _M_default_append(__new_size - size());
        ^
test.cpp:7:7: note: in instantiation of member function 'std::vector<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>::resize' requested here
    v.resize(10);
    ^
In file included from test.cpp:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/memory:65:
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_construct.h:109:38: error: call to deleted constructor of 'std::unique_ptr<int, std::default_delete<int>>'
    { ::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...); }
                                    ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:91:8: note: in instantiation of function template specialization 'std::_Construct<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &>' requested here
                std::_Construct(std::__addressof(*__cur), *__first);
                    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:150:2: note: in instantiation of function template specialization 'std::__uninitialized_copy<false>::__uninit_copy<std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &, const std::unique_ptr<int, std::default_delete<int>> *>, std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, std::unique_ptr<int, std::default_delete<int>> &, std::unique_ptr<int, std::default_delete<int>> *>>' requested here
        __uninit_copy(__first, __last, __result);
        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &, const std::unique_ptr<int, std::default_delete<int>> *>, std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, std::unique_ptr<int, std::default_delete<int>> &, std::unique_ptr<int, std::default_delete<int>> *>>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_deque.h:896:14: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, const std::unique_ptr<int, std::default_delete<int>> &, const std::unique_ptr<int, std::default_delete<int>> *>, std::_Deque_iterator<std::unique_ptr<int, std::default_delete<int>>, std::unique_ptr<int, std::default_delete<int>> &, std::unique_ptr<int, std::default_delete<int>> *>, std::unique_ptr<int, std::default_delete<int>>>' requested here
    { std::__uninitialized_copy_a(__x.begin(), __x.end(),
            ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_queue.h:96:11: note: in instantiation of member function 'std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>::deque' requested here
    class queue
        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:91:8: note: (skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
                std::_Construct(std::__addressof(*__cur), *__first);
                    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_uninitialized.h:346:19: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<const std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>' requested here
    return std::__uninitialized_copy_a
                ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/vector.tcc:659:14: note: in instantiation of function template specialization 'std::__uninitialized_move_if_noexcept_a<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>> *, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>' requested here
                    std::__uninitialized_move_if_noexcept_a(
                        ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/stl_vector.h:940:4: note: in instantiation of member function 'std::vector<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>::_M_default_append' requested here
        _M_default_append(__new_size - size());
        ^
test.cpp:7:7: note: in instantiation of member function 'std::vector<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>, std::allocator<std::queue<std::unique_ptr<int, std::default_delete<int>>, std::deque<std::unique_ptr<int, std::default_delete<int>>, std::allocator<std::unique_ptr<int, std::default_delete<int>>>>>>>::resize' requested here
    v.resize(10);
    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/unique_ptr.h:468:7: note: 'unique_ptr' has been explicitly marked deleted here
    unique_ptr(const unique_ptr&) = delete;
    ^
2 errors generated.

这在libc++中似乎很好,例如clang++ test.cpp -o test -stdlib=libc++

我这是一个已知的libstdc++错误吗?知道怎么解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-04 09:31:49

这不是窃听器。std::queue<std::unique_ptr<int>>的移动构造函数是noexcept(true)在libc++中,而不是在libstdc++中。因此,对于libstdc++,std::vector必须使用复制构造函数进行重新分配。但是它的调用会生成一个编译器错误,因为自然地,一个唯一指针的队列可能不会被复制。

证明:https://godbolt.org/z/9j9P59

请注意,这不是一个bug,因为标准没有为std::queue规定移动构造函数为noexcept。然而,实现是允许加强异常规范

实现可以通过添加非抛出异常规范来增强非虚拟函数的异常规范。

这就是libc++在这里所做的:https://github.com/llvm/llvm-project/blob/master/libcxx/include/queue#L241

票数 5
EN

Stack Overflow用户

发布于 2020-12-04 10:06:50

如果你阅读libstdc++的源代码,在向量的调整大小,它最终调用,

代码语言:javascript
复制
std::__uninitialized_move_if_noexcept_a

函数将旧内存空间移动或复制到新内存空间。

此函数所做的是,如果移动构造函数不抛出,则移动底层对象,否则复制它。

如果您阅读std::queue的libstdc++实现,

代码语言:javascript
复制
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
queue(queue&& __q, const _Alloc& __a)
   : c(std::move(__q.c), __a) { }

显然后面没有noexcept,这意味着它可能会抛出。因此,libstdc++将在调整大小时调用队列的复制构造函数,并且无法复制std::unique_ptr,因此存在编译错误。

坦率地说,这应该在c++11之后起作用,即使它不是一个bug,而是在前C++11时代的一种旧行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65140603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档