假设我有一个按值返回 STL 容器的函数,例如 std::list
std::list<Foo> get_Foolist()
{
std::list<Foo> lst;
//populate lst
return lst;
}
or
class SomeClass
{
std::list<Foo> get_Foolist()
{
return m_foolst;
}
...
private:
std::list<Foo> m_foolst;
};
现在,我有一段代码,它使用此函数来获取列表并按以下方式迭代它,
std::list<Foo>::iterator i = get_Foolist().begin();
//use i like ... cout << *i << endl;
当我看到这段代码时,我觉得它不应该工作,因为我们在临时对象上使用迭代器,该对象将在执行表达式后被删除。但是,令我惊讶的是它确实有效。
这适用于 STLPort5.2 和 Microsoft Visual Studio 2008。
后来,当我们删除 STLPort 并开始使用编译器提供的 STL 实现时,我们开始面临崩溃。
据透露,上面的代码不适用于 VS 2008 列表实现,但适用于 STLPort。
我尝试在其他各种编译器上运行它,结果如下,
- Visual Studio 2008(没有 STLport5.2)- 崩溃
- Visual Studio 2008(带 STLPort5.2)- 可以使用
- Visual Studio 2013(没有 STLport5.2)- 崩溃
- GCC 4.3.6(没有 STLPort5.2)- 可以使用
- Clang 3.0(没有 STLPort5.2)- 可以使用
(GCC 和 Clang 是从http://melpon.org/wandbox/)
现在我的问题是,
- 哪种实现是正确的(根据标准)?
- 为什么它在 VS 以外的所有实现上都成功了?
- 哪种实现是正确的(根据标准)?
想必他们都是。
- 为什么它在 VS 以外的所有实现上都成功了?
It is 未定义的行为因为您正在取消引用无效的迭代器。因此它可能会以无数种方式失败。或者看起来有效,这只是另一种失败模式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)