临时容器对象上的迭代器

har*_*had 2 c++ stl

假设我有一个按值返回STL容器的函数,比如std :: list

std::list<Foo> get_Foolist()
{
    std::list<Foo> lst;
    //populate lst
    return lst;
}
Run Code Online (Sandbox Code Playgroud)

要么

class SomeClass
{
    std::list<Foo> get_Foolist()
    {
        return m_foolst;
    }
    ...
    private:
    std::list<Foo> m_foolst;
};
Run Code Online (Sandbox Code Playgroud)

现在,我有一段代码,它使用此函数获取列表并按以下方式迭代它,

std::list<Foo>::iterator i = get_Foolist().begin();
//use i like ... cout << *i << endl;
Run Code Online (Sandbox Code Playgroud)

当我看到这段代码时,我觉得它不应该工作,因为我们在临时对象上使用迭代器,这会在执行表达式后被删除.但令我惊讶的是,它正在发挥作用.

这适用于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/)

现在我的问题是,

  1. 哪种实现是正确的(按照标准)?
  2. 为什么它在VS之外的所有实现上都成功了?

jua*_*nza 5

  1. 哪种实现是正确的(按照标准)?

大概都是他们所有人.

  1. 为什么它在VS之外的所有实现上都成功了?

它是未定义的行为,因为您正在取消引用无效的迭代器.所以它可以以无数种方式失败.或者似乎工作,这只是另一种失败模式.