对复制构造函数已被删除的对象向量进行迭代 (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&
的问题吗?
不!不是auto
的问题。推导auto
时,不推导引用。按设计。
auto
总是推导出非引用类型,无论是用于范围迭代变量还是任何其他变量。因此,要推断出引用,您必须将其设为一个,auto &
。将auto
视为任何非引用 类型的占位符通配符。以上是关于对复制构造函数已被删除的对象向量进行迭代 (C2280)的主要内容,如果未能解决你的问题,请参考以下文章