c++自动变量(map)被赋予了垃圾值

  • 本文关键字:变量 map c++ c++ auto
  • 更新时间 :
  • 英文 :


我尝试按如下方式分配"a"变量:

for (auto& a : getMap()[1])

其将垃圾值分配给CCD_ 1。但是,如果我在如下所示首先声明变量后使用它,它就可以正常工作。

auto vv = getMap()[1];
for (auto& a : vv)

如果我在不声明变量的情况下立即使用它,为什么会出现问题?

#include <string>
#include <map>
#include <memory>
#include <vector>
using namespace std;
typedef struct _mystruct {
} mystruct;
map<int, vector<shared_ptr<mystruct>>> mymap;
void init() {
vector<shared_ptr<mystruct>> v;
v.push_back(make_shared<mystruct>(mystruct()));
mymap[1] = v;
}
map<int, vector<shared_ptr<mystruct>>> getMap() {
return mymap;
}
int main()
{
init();
vector<shared_ptr<mystruct>> v2;
for (auto& a : getMap()[1]) {
v2.push_back(a);
}
auto vv = getMap()[1];
for (auto& a : vv) {
v2.push_back(a);
}
return 0;
}

直到C++17(此后发生变化的细节不会改变答案(,基于范围的for循环等效于(取自cppreference(:

{    
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {    
range_declaration = *__begin;
loop_statement   
}    
}

因为您的getMap返回地图的副本,所以:

auto&& __range = getMap()[1];

是对映射的临时副本中的一个元素的引用,该元素在该语句结束时被销毁。CCD_ 3则保持一个悬空引用。无论如何,您可能不想仅仅为了迭代其中一个元素而复制整个映射,因此返回一个(const(引用而不是getMap的副本将解决此问题。

当你写:

auto vv = getMap()[1];

vv是来自映射的向量的副本。因此,在这种情况下不存在悬空引用。

基于范围的循环是这样的:

{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
} 

其中range_expression是代码中的getMap()[1]。但问题是getMap()[1]是一个临时变量,它的寿命将在auto && __range = range_expression ;之后结束。所以范围循环通常是无效的。

最新更新