【问题标题】:Object lifetime issue with range-based for loop基于范围的 for 循环的对象生命周期问题
【发布时间】:2014-01-18 17:05:16
【问题描述】:

我目前正在将我的代码转换为 C++11,并且在使用以下基于范围的 for 循环时遇到了问题(FWIW,相同的代码之前使用 BOOST for_each 运行得很好)。

mLibraryFiles 成员(STL 向量)是单例实例的一部分,保证在方法返回后存在,但是当调用者检查返回的对象时,它只包含垃圾。

在从方法返回后,通过它进行调试似乎从预期的内容变成了垃圾,所以我想我一定对 C++11 基于范围的循环的实际工作方式有什么误解:

Entry* FindEntry(string inName)
{  Entry *rs = NULL;

   for (auto libraryEntry : mLibraryFiles)
   {
      if (libraryEntry.filename.compare(inName) == 0)
      {
         rs = &libraryEntry;
         break;
      }
   }

   return rs;
}

我原以为libraryEntry 变量代表mLibraryFiles 向量中的实际对象?

非常感谢任何见解!
(编译器是 LLVM 5.0,虽然我怀疑这很重要..)

【问题讨论】:

  • libraryEntrymLibraryFiles 元素的副本。请改用for (auto& libraryEntry : mLibraryFiles)
  • llvm 当前不是 3.4 版。您可能是指 clang?
  • @Nil Apple 为其 LLVM 版本使用单独的版本编号方案。 (是的,LLVM is currently at version 3.4。)Apple 的版本不一定与上游 LLVM 版本一致,因此它们使用不同的编号方案来“避免混淆”。
  • 啊!很高兴知道,谢谢。
  • @Nil 是的,很抱歉造成混淆 - Xcode 5 中显示的版本,其中指出 Apple LLVM 5.0

标签: c++ c++11 for-loop auto object-lifetime


【解决方案1】:

您的向量中的值在循环中被复制到 libraryEntry,因此您有一个指向复制值的指针,该指针在循环后不再存在。使用auto& libraryEntry

【讨论】:

    【解决方案2】:

    libraryEntry 声明为auto&,否则它是一个临时副本,其生命周期绑定到for循环。这就是为什么我更喜欢写对象的实际类型而不是auto

    【讨论】:

    • herb sutter 说尽可能使用 auto 并避免使用实际类型。它免费为您提供 typedef 的灵活性。
    • 编写实际类型,同样没有&,同样糟糕。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-26
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多