c++ - 为什么无法分配给本身缺少复制运算符的对象 vector ?

标签 c++ c++11 vector stdvector

我有一个可复制构造但不可赋值的结构 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/

相关文章:

C++:追加到 vector 字符串

c++ - 如何为 VS2008 __forceinline 函数?

c++ - 在 C++ 应用程序中使用 Tensorflow : How to release GPU memory

c++ - 不稳定的单例成员?

c++ - 如何让我的嵌套类进入模板化类以接受自身的其他版本?

c++ - 为什么 memory_order_relaxed 和 memory_order_seq_cst 没有区别?

c++ - 使用互斥量时尝试引用已删除的函数

c++ - 我如何将我的程序变成我可以安装的东西?

c++ - 在 C++ 中使用双指针声明原子的动态数组是否正确?

c++ - 编写一个函数来查找整数 vector 的中位数