插入具有没有复制构造函数的对象的向量
我有一个类的拷贝构造函数被显式删除(因为 A 在内部使用指针,我不想陷入浅拷贝陷阱):
class A {上市:A(const A&) = 删除;A&运算符=(const A&) = 删除;A(const B& b, const C& c);}
现在我有一个 vector 类型的向量.aVector;
并且我想在其中插入元素 - 所以我使用 emplace_back
:
aVector.emplace_back(b, c);
但是,这无法使用 gcc 进行编译,并且出现错误 -
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_construct.h:在'的实例化中void std::_Construct(_T1*, _Args&&...)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:77:3: 需要来自'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:119:41:来自'_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:260:63: 需要来自'_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:283:67:来自'_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:410:6: 'void std 要求::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...)第三方/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:102:4: 'void std: 要求::vector<_Tp, _Alloc>::emplace_back(_Args&& ...)
这个错误的原因是什么,如何在不删除复制构造函数的情况下修复它?我是否需要移动构造函数 - 是否需要明确定义?
解决方案您应该添加移动构造函数 - 因为 std::vector::emplace_back
可能会执行需要复制/移动构造函数的重定位.或者只是使用 std::deque
.
现场演示
#include <向量>#include <deque>使用命名空间标准;结构 NoCopyNoMove{NoCopyNoMove(const NoCopyNoMove&) = 删除;NoCopyNoMove&运算符=(const NoCopyNoMove&)=删除;NoCopyNoMove(NoCopyNoMove&&) = 删除;NoCopyNoMove&运算符=(NoCopyNoMove&&)=删除;NoCopyNoMove(int){};};结构仅移动{OnlyMove(const OnlyMove&) = delete;OnlyMove&运算符=(const OnlyMove&)=删除;OnlyMove(OnlyMove&&) noexcept {}OnlyMove&operator=(OnlyMove&&) noexcept {}OnlyMove(int){};};int main(){双端队列X;x.emplace_back(1);矢量y;y.emplace_back(1);}
<小时><块引用>
§ 23.2.3 表 101 ― 可选的序列容器操作
a.emplace_back(args)
[...]
要求:T
应该是 EmplaceConstructible
从 args 到 X
的.对于vector
,T
也应该是MoveInsertable
到 X
.
I have a class whose copy constructors are explicitly deleted (because A uses pointers internally and I don't want to fall into shallow copy pitfalls):
class A {
public:
A(const A&) = delete;
A& operator=(const A&) = delete;
A(const B& b, const C& c);
}
Now I have a vector of type vector<A> aVector;
and I want to insert elements into it - so I use emplace_back
:
aVector.emplace_back(b, c);
However, this fails to compile using gcc and I get the error -
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:77:3: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:119:41: required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:260:63: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:283:67: required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:410:6: required from 'void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:102:4: required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...)
What is the reason for this error and how can it be fixed without removing the deletion of the copy constructors? Do I need a move constructor - does it need to be explicitly defined?
解决方案You should add move constructor - because std::vector::emplace_back
may do relocation which requires copy/move constructor. Or just use std::deque
.
LIVE DEMO
#include <vector>
#include <deque>
using namespace std;
struct NoCopyNoMove
{
NoCopyNoMove(const NoCopyNoMove&) = delete;
NoCopyNoMove& operator=(const NoCopyNoMove&) = delete;
NoCopyNoMove(NoCopyNoMove&&) = delete;
NoCopyNoMove& operator=(NoCopyNoMove&&) = delete;
NoCopyNoMove(int){};
};
struct OnlyMove
{
OnlyMove(const OnlyMove&) = delete;
OnlyMove& operator=(const OnlyMove&) = delete;
OnlyMove(OnlyMove&&) noexcept {}
OnlyMove& operator=(OnlyMove&&) noexcept {}
OnlyMove(int){};
};
int main()
{
deque<NoCopyNoMove> x;
x.emplace_back(1);
vector<OnlyMove> y;
y.emplace_back(1);
}
§ 23.2.3 Table 101 ― Optional sequence container operations
a.emplace_back(args)
[...]Requires:
T
shall beEmplaceConstructible
intoX
from args. Forvector
,T
shall also beMoveInsertable
intoX
.
相关文章