持有对多重嵌套std :: vector的引用的正确方法是什么?

时间:2019-09-19 14:23:54

标签: c++ reference segmentation-fault c++17 declaration

我正在对我们的应用程序进行性能分析,发现诸如以下的构造会占用大量时间:

void Locations::remove_without_set_index(Item *item) {
  locations[item->x()][item->y()][item->z()].back()->LocationIndexHandler::set_index(item->LocationIndexHandler::index());
  locations[item->x()][item->y()][item->z()][item->LocationIndexHandler::index()] = locations[item->x()][item->y()][item->z()].back();
  locations[item->x()][item->y()][item->z()].pop_back();
}

因此,似乎合理的方法是只获取一次引用,然后使用该引用,而不是对其进行多次调用。但是,当我这样做时:

void Locations::remove_without_set_index(Item *item) {
  auto reference = locations[item->x()][item->y()][item->z()];
  reference.back()->LocationIndexHandler::set_index(item->LocationIndexHandler::index());
  reference[item->LocationIndexHandler::index()] = reference.back();
  reference.pop_back();
}

我最终遇到了分段错误和错误,例如损坏的双向链接列表。数据结构定义如下:

std::vector<std::vector<std::vector<std::vector<Item*>>>> locations;

因此,我假设我要获取的引用不正确。是否可以正确保存引用?如果可以,如何保存?

2 个答案:

答案 0 :(得分:4)

您的参考不是参考。是副本。您需要这样做:

auto& reference = locations[item->x][item->y][item->z];
//  ^

C ++默认情况下是值语义的,您必须选择加入参考。

答案 1 :(得分:0)

似乎您忘记了此表达式中的括号

auto reference = locations[item->x()][item->y()][item->z()];
                                  ^^         ^^         ^^

或这种掩饰

locations[item->x()][item->y()][item->z()].back()->LocationIndexHandler::set_index(item->LocationIndexHandler::index()); 

应写成无括号。

无论如何,您还可以使用以下方法定义参考

decltype( auto ) reference = ( locations[item->x()][item->y()][item->z()] );