我有一个可复制构造但不可赋值的结构 vector :
struct Struct
{
inline Struct(const std::string& text, int n) : _text(text), _n(n) {}
inline Struct(const Struct& other) : _text(other._text), _n(other._n) {}
const std::string _text;
const int _n;
Struct& operator=(const Struct&) = delete;
};
一切正常。事实上,我什至可以通过 std::vector<Struct>
around by value 作为函数的返回值。然而,这失败了:
std::vector<TextFragment> v1, v2;
v2 = v1;
当然,错误是:
error: C2280: 'Struct &Struct ::operator =(const Struct &)' : attempting to reference a deleted function
我不明白为什么它会尝试调用它。这是避免重新分配 vector 的内存块的某种优化吗?..
最佳答案
Is that some kind of an optimization to avoid re-allocating the vector's memory block?..
差不多。这是一种优化,可避免重新分配 vector
中可能存在的任何内存块。的 value_type
.也就是说,这是一个全局假设,即赋值比销毁后复制构造更有效。
例如考虑 vector<string>
分配,对于两个大小相等的 vector
s,和一堆大小相同的 string
vector
中的每个位置都有 s :
v2 = v1;
这个操作要做的就是memcpy
每个string
.根本没有分配。减少分配/取消分配是当今最重要的优化之一。
但是,您的 Struct
并没有失去一切。 .你想要做的是指示 vector
您不想分配您的 Struct
s,而是销毁它们,然后从 v1
复制构造它们.这样做的语法是:
v2.clear();
for (const auto& x : v1)
v2.push_back(x);
如以下评论所述,您还可以复制构造 v1
, 然后 swap
与拷贝。您要么需要创建 v1
的临时本地拷贝, 或者你需要使用 v1
关于成员互换的“lhs”:
std::vector<Struct>(v1).swap(v2);
我个人觉得这很难读。在 C++11/14 中,我更喜欢这种涉及移动赋值的替代方案:
v2 = std::vector<Struct>(v1);
这些替代品更容易让人眼前一亮。但第一种选择,使用 clear()
和 push_back
将是平均效率最高的。这是因为第一个备选方案是唯一有机会重用 capacity()
的备选方案在v2
.其他两个总是重新创建新的capacity()
在 v1
的拷贝中扔掉v2
现有 capacity()
.
关于c++ - 为什么无法分配给本身缺少复制运算符的对象 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37309103/