在std::vector中就地构造一对不可移动、不可复制的
In place construction of a pair of nonmovable, non copyable in a std::vector
假设以下不可复制且不可移动的结构 X
没有默认构造函数且没有单个参数构造函数:
struct X
{
X(int x, int y) { }
X(const X&) = delete;
X(X&&) = delete;
};
和一个向量 std::vector<pair<X,X>> v
。要插入到 v
中,可以使用 emplace_back
如果 X
仅可从一个参数构造,因为它有效地调用了 std::pair<X,X>
的构造函数。
我们可以这样做:
v.emplace_back(X(42,42),X(69,69));
但在这种情况下, X
的移动构造函数被调用,后者无法编译。由于这是不可能的,我们必须使用 std::pair 的 std::piecewise_construct
构造函数并调用:
v.emplace_back(std::piecewise_construct, std::forward_as_tuple(42,42), std::forward_as_tuple(69,69));
我希望它能正常工作,但出于某种原因,向量正在调用 move ctor(或复制,如果只删除 move)。
例如将容器更改为 std::list
,一切正常。将 <
运算符添加到 X
并创建 std::map<X,X>
(具有成对的 X 作为节点)或 std::set<std::pair<X,X>>
并使用 emplace
而不是 emplace_back
一切似乎都有效。 std::vector
有什么问题?
可以找到完整的代码片段 here。
一旦大小达到容量,std::vector
将重新分配。
当将元素重新分配到新的内存段时,std::vector 必须 copy/move 来自旧段的值,这是通过调用 copy/move 构造函数实现的。
如果您不需要元素在内存中是连续的,您可以使用 std::deque
,因为 std::deque
不会在内部重新分配元素。
您不能将不可复制和不可移动的对象存储到 std::vector
s 中。
@François Andrieux 建议编辑
如果出于任何原因您仍然需要 std::vector
,您可能会考虑使用使用 std::unique_ptr<X>
作为 值类型 使用 [=16] 制作的向量=].
使用此解决方案,您仍然无法在内存中获得元素的顺序,并且它们会一直保存在内存中,直到它们仍在向量中,所以除非您出于任何原因被迫使用 std::vector
s,我认为最好的匹配仍然是 std::deque
.
假设以下不可复制且不可移动的结构 X
没有默认构造函数且没有单个参数构造函数:
struct X
{
X(int x, int y) { }
X(const X&) = delete;
X(X&&) = delete;
};
和一个向量 std::vector<pair<X,X>> v
。要插入到 v
中,可以使用 emplace_back
如果 X
仅可从一个参数构造,因为它有效地调用了 std::pair<X,X>
的构造函数。
我们可以这样做:
v.emplace_back(X(42,42),X(69,69));
但在这种情况下, X
的移动构造函数被调用,后者无法编译。由于这是不可能的,我们必须使用 std::pair 的 std::piecewise_construct
构造函数并调用:
v.emplace_back(std::piecewise_construct, std::forward_as_tuple(42,42), std::forward_as_tuple(69,69));
我希望它能正常工作,但出于某种原因,向量正在调用 move ctor(或复制,如果只删除 move)。
例如将容器更改为 std::list
,一切正常。将 <
运算符添加到 X
并创建 std::map<X,X>
(具有成对的 X 作为节点)或 std::set<std::pair<X,X>>
并使用 emplace
而不是 emplace_back
一切似乎都有效。 std::vector
有什么问题?
可以找到完整的代码片段 here。
std::vector
将重新分配。
当将元素重新分配到新的内存段时,std::vector 必须 copy/move 来自旧段的值,这是通过调用 copy/move 构造函数实现的。
如果您不需要元素在内存中是连续的,您可以使用 std::deque
,因为 std::deque
不会在内部重新分配元素。
您不能将不可复制和不可移动的对象存储到 std::vector
s 中。
@François Andrieux 建议编辑
如果出于任何原因您仍然需要 std::vector
,您可能会考虑使用使用 std::unique_ptr<X>
作为 值类型 使用 [=16] 制作的向量=].
使用此解决方案,您仍然无法在内存中获得元素的顺序,并且它们会一直保存在内存中,直到它们仍在向量中,所以除非您出于任何原因被迫使用 std::vector
s,我认为最好的匹配仍然是 std::deque
.