Сохранить выбранные поля из неупорядоченного набора в структуре в вектор - PullRequest
2 голосов
/ 09 апреля 2019

У меня есть unordered_set, в котором хранится следующая структура

struct match_t{
  size_t score;
  size_t ci;  
};

typedef std::unordered_set<match_t> uniq_t;

Теперь я хочу сохранить элементы uniq_t myset; в векторе, но при этом я хочу скопировать только счет, а не весь struct. Я видел решения для назначения элементов, используя assign или back_inserter. Мне было интересно, как выбрать только обязательные поля из структуры. Я не вижу никаких параметров в assign или back_inserter для этой цели.

Должен ли я попробовать переопределить push_back метод для вектора или есть другие методы для этого?

РЕДАКТИРОВАТЬ 1 Получу ли я какие-либо улучшения производительности, используя любой из этих методов вместо циклического перебора набора и присвоения необходимых значений?

1 Ответ

5 голосов
/ 09 апреля 2019

Нет ничего плохого в простом цикле for:

std::unordered_set<match_t> myset;
std::vector<std::size_t> myvec;

myvec.reserve(myset.size()); // allocate memory only once

for (const auto& entry : myset)
    myvec.push_back(entry.score);

В качестве альтернативы, вы можете использовать std::transform с пользовательской лямбдой:

#include <algorithm>

std::tranform(myset.cbegin(), myset.cend(), std::back_inserter(myvec),
    [](const auto& entry){ return entry.score; });

Другой способ - использовать диапазонбиблиотека, например, с range-v3

#include <range/v3/view/transform.hpp>

std::vector<std::size_t> myvec = myset | ranges::view::transform(&match_t::score);

С точки зрения производительности, вы ничего не можете сделать с линейным проходом по всем match_t объектам.Вместо этого важная настройка заключается в минимизации количества выделений.Поскольку размер результирующего std::vector известен априори, вызов std::vector::reserve, как показано выше, гарантирует, что ненужное распределение не произойдет.

...