c++ 中的 range-for 会调用项目的复制构造函数吗?

Posted

技术标签:

【中文标题】c++ 中的 range-for 会调用项目的复制构造函数吗?【英文标题】:Will range-for in c++ calls item's copy constructor? 【发布时间】:2019-08-30 02:07:09 【问题描述】:

PanelItem 是一个没有复制构造函数的类 (=Deleted)。我使用QList<PanelItem> m_arrPanelItems 来存储它们。

当我调用QList::append(const T &value) 时,出现错误'PanelItem::PanelItem(const PanelItem &)': attempting to reference a deleted function。我认为它在函数内部调用了PanelItem::PanelItem(const PanelItem &)

当我使用 range-for 时,错误再次出现。我在 range_declaration 中使用const auto&。所以我认为不会使用复制构造函数PanelItem::PanelItem(const PanelItem &)

// QList<PanelItem> m_arrPanelItems
for (const auto& t_item : this->m_arrpPanelItems) 
    // do something 

为什么?

【问题讨论】:

您似乎一开始就说不能将它们添加到容器中,那么您要迭代的容器中有什么? @RetiredNinja 也许这些项目被放置/移动到列表中而不是复制?谁知道。但是基于范围的 for 循环在使用引用变量时不应该调用复制语义。如果是的话,有什么东西坏了 The values stored in the various containers can be of any assignable data type. To qualify, a type must provide a copy constructor, and an assignment operator. 【参考方案1】:

QList::append(const T &amp;value) "在列表末尾插入值。" - 从签名及其功能来看,T 需要有一个复制构造函数才能使该函数工作......

正如 thuga 已经指出的那样,要存储的类型例如QList 必须 是 assignable types - 这意味着他们需要有一个复制构造函数 - 才能成为放入 QList 中的有效类型。对于没有复制构造函数(和/或赋值运算符)的类型,API 甚至声明您需要存储 pointers (T*)。

即使您以某种方式设法将类型 没有 复制构造函数放入 QList 您违反了该要求,导致各种未定义的行为:范围声明中的错误可能例如源于某种内部魔法 QList 正在做的事情(例如,implicitly shared 类型),但这一切都没有实际意义,因为首先不允许您将没有复制构造函数的类型放入 QLists .换句话说:垃圾进,垃圾出。

【讨论】:

以上是关于c++ 中的 range-for 会调用项目的复制构造函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

在一个多模块的python项目中,如何在子模块中引用项目的根目录?

在单元测试期间获取引用项目的路径

源生成器:有关引用项目的信息?

可用项目的 Django ListView 查询集

如何使用项目的其他值搜索 Vuetify 数据表

如何让 Storybook 使用项目的 CSS 变量