对复制构造函数已被删除的对象向量进行迭代 (C2280)

Posted

技术标签:

【中文标题】对复制构造函数已被删除的对象向量进行迭代 (C2280)【英文标题】:Iteration over a vector of objects whose copy constructor has been deleted (C2280) 【发布时间】:2019-08-22 01:35:30 【问题描述】:

我有一个类,其复制构造函数已被删除。当尝试遍历包含此类对象的std::vector 时,我无法以“不错”的方式进行操作,而必须使用某种迭代变量。

struct foo 

foo() :
    val(0)


foo(const foo&) = delete;

int val;

;

int main() 

std::vector<foo> fooVec(5);

for (auto f : fooVec) //C2280 - attempting to reference a deleted function!

    std::cout << f.val << std::endl;


for (int i = 0; i < fooVec.size(); i++) //no problems

    std::cout << fooVec[i].val << std::endl;



是否有一种巧妙的方法可以在不需要使用迭代变量的情况下对不可复制对象的向量进行迭代?

我非常热衷于学习如何使用现代功能,并且正在尝试学习如何正确处理特殊成员函数,作为现代化某些现有代码的一部分(我们仍然有原始指针)。

【问题讨论】:

What type is in the range for loop?的可能重复 【参考方案1】:

比你想象的要简单:

for (auto &f : fooVec)

作为额外的奖励,您可以修改这个f,就在它位于向量中的位置,在它当前的家中很舒服。使用基本的按值迭代时:

for (auto f : fooVec)

这会复制向量中的每个值(因此会出现问题),对 f 的任何更改都不会影响向量中的原始值。

但是当您使用引用进行迭代时,不会复制,您可以在迭代时修改每个值。

或者,如果您希望继续让编译器为您发现错误:

for (const auto &f : fooVec)

这仍在迭代,但每个引用的 f 值都是 const 并且不可修改。

【讨论】:

我明白了!这是auto 错误地将类型推断为foo 而不是foo&amp; 的问题吗? 不!不是auto的问题。推导auto 时,不推导引用。按设计。 auto 总是推导出非引用类型,无论是用于范围迭代变量还是任何其他变量。因此,要推断出引用,您必须将其设为一个,auto &amp;。将auto 视为任何非引用 类型的占位符通配符。

以上是关于对复制构造函数已被删除的对象向量进行迭代 (C2280)的主要内容,如果未能解决你的问题,请参考以下文章

使用迭代器 C++ 删除对象类型的向量元素

当我对具有复制构造函数但没有赋值运算符的对象进行赋值时会发生啥?

C ++在向量迭代中删除并返回指向对象的指针

在将对象插入向量时了解构造,复制和销毁

对包含动态表的对象进行 stable_sort

vector 如何在特定位置调用复制构造函数?