【问题标题】:boost::multi_index_container in QMapQMap 中的 boost::multi_index_container
【发布时间】:2014-12-02 04:35:31
【问题描述】:

是否可以使用QMap< QString, boost::multi_index_container<...> > 之类的结构?

一方面,我们有private: BOOST_COPYABLE_AND_MOVABLE(multi_index_container) 在容器声明中。它应该告诉我们不要将 multi_index_container 放入其他类似 stl 的容器中。

另一方面,这样的构造

QMap< QString, boost::multi_index_container<...> > _map;
map.insert("bla-bla", container1);
...
auto tmp = _map.value(QString("bla-bla")).get<keyVal>();
//keyVal corresponds to one for the multi_index_container instance

使用 Visual Studio 2012 (+update4 + boost v1.55 + qt v4.8.5) 编译良好。

实验发现:

auto tmp = _map.value(QString("bla-bla")).get<keyVal>();

tmp 处理已删除的数据。 而

auto tmp = _map.value(QString("bla-bla"));
auto tmp_1 = tmp.get<keyVal>();

tmp_1留下有效数据。

如果我们需要将boost::multi_index_container&lt;&gt; 放在另一个容器中,有人知道如何正确处理它吗?

Qt5.3 有什么不同吗?

【问题讨论】:

  • “你在实验中发现”编译器会很乐意编译你的 [Undefined Behaviour]()。对于绝大多数此类情况,它们不需要发出诊断消息。

标签: qt boost move-semantics qt4.8 qt5.3


【解决方案1】:

如您在 QMap 的文档中所见:

const T QMap::value(const Key & key, const T & defaultValue = T()) const

值是按值返回的,而不是按引用返回的。除了对于大值(例如多索引容器,可能吗?)非常低效之外,它还返回一个临时值。

现在,get&lt;keyVal&gt;(); 确实返回了对第一个索引的引用,它属于临时索引,它在包含完整表达式的末尾死亡。


要获得可修改的引用,请使用

T & QMap::operator[](const Key & key)

现在你可以:

auto& tmp = _map[QString("bla-bla")].get<keyVal>();

注意&amp;

【讨论】:

    【解决方案2】:

    添加到@sehe 关于如何检索引用而不是临时值的答案,boost::multi_index_container copyable and movable。您引用的这个BOOST_COPYABLE_AND_MOVABLE 宏必须放在类私有部分(如here 指定),但这不会影响复制/移动ctors 的可见性。故事的寓意:在深入研究代码之前咨询文档。

    【讨论】:

    • 很抱歉这篇文章被否决了。我认为 OP 对 SO 来说是新的。来自我的 +1。
    • 谢谢@sehe!并不是说我太在乎我的 SO 声誉 :-) 我唯一的动机是试图帮助人们使用我的库。
    【解决方案3】:

    在我的特殊情况下,问题在于编译器使用了const T operator[](const Key &amp; key) const 而不是T &amp; operator[](const Key &amp; key),因为类的方法是const,而映射是类的一个字段。

    【讨论】:

    • 这不是答案,你问题中的代码没有这个问题,你的类型都是auto推导出来的。您问的问题是我在回答中解释的 [Undefined Behaviour]() (“使tmp 处理已删除的数据”)。如果您修复之后修复不相关的东西,那么,那是不相关的。
    • 问题不在于未定义的行为。问题是关于使用 boost::multi_index_container 实例作为 QMap 值的特殊情况。所以我的回答完全与问题有关。作为一个附加问题,我询问了一些关于 boost::multi_index_container 实现的信息。因此,虽然引用文档总是有用的,但它与问题没有直接关系。通过自动推断类型不是问题的根源,因此您的评论没有建设性。
    • “让 tmp 处理已删除的数据”和“有人知道什么是正确的处理方法吗”完全是关于 UB,实际上 什么都没有与多索引有关。在使用 auto tmp = map.value(QString("keyname")).c_str() 的 QMap 中,您会遇到完全相同的问题(未定义行为)
    • 顺便说一句,将变量推断为auto 是相关的,因为只有auto&amp; 需要引用。未定义的行为源于持有对 temporaries.references 的悬空引用)。我的印象是你并没有真正理解你必须解决的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 2010-12-14
    • 1970-01-01
    相关资源
    最近更新 更多