Как правильно хранить ссылку на многократно вложенный std :: vector? - PullRequest
0 голосов
/ 19 сентября 2019

Я нахожусь в процессе профилирования нашего приложения и обнаружил, что такие конструкции, как следующие, занимают значительное количество времени:

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 ]

4 голосов
/ 19 сентября 2019

Ваша ссылка не является ссылкой.Это копия.Вам нужно сделать следующее:

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

C ++ - это значение-семантика по умолчанию, вы должны согласиться на получение ссылки.

0 голосов
/ 19 сентября 2019

Кажется, вы забыли скобки в этом выражении

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()] );
...