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 &value)
"在列表末尾插入值。" - 从签名及其功能来看,T
需要有一个复制构造函数才能使该函数工作......
正如 thuga 已经指出的那样,要存储的类型例如QList
必须 是 assignable types - 这意味着他们需要有一个复制构造函数 - 才能成为放入 QList
中的有效类型。对于没有复制构造函数(和/或赋值运算符)的类型,API 甚至声明您需要存储 pointers (T*
)。
即使您以某种方式设法将类型 没有 复制构造函数放入 QList
您违反了该要求,导致各种未定义的行为:范围声明中的错误可能例如源于某种内部魔法 QList
正在做的事情(例如,implicitly shared 类型),但这一切都没有实际意义,因为首先不允许您将没有复制构造函数的类型放入 QList
s .换句话说:垃圾进,垃圾出。
【讨论】:
以上是关于c++ 中的 range-for 会调用项目的复制构造函数吗?的主要内容,如果未能解决你的问题,请参考以下文章