как разыменовать уникальные указатели и применить их к std :: transform - PullRequest
0 голосов
/ 02 августа 2020

У меня есть набор std::set<std::unique_ptr<T>, compare> myset{};, где сравнение

struct compare {
    auto operator()(std::unique_ptr<T> const& a, std::unique_ptr<T> const& b) const noexcept -> bool
    {
        return a.get() < b.get();
    }
};

Это (надеюсь, но я мог ошибаться), сортирует уникальные указатели в наборе таким образом, что базовые значения находятся в порядке возрастания (содержимое памяти, а не адреса указателей). Затем у меня есть следующий код для создания вектора значений, на которые указывают вышеупомянутые уникальные указатели:

auto vec = std::vector<T>();
std::transform(myset.begin(), myset.end(), vec.begin(), [&](std::unique_ptr<T> ptr) -> T {
    return ptr.get();
});
return vec;

Но этот код не работает из-за ошибки в способе, которым я разработал преобразование, очевидно - правильно ли я «разыменовываю» (получаю значения, на которые указывают указатели) уникальные указатели?

1 Ответ

1 голос
/ 02 августа 2020

get возвращает указатель на управляемый объект. Вы хотите *. Вам также необходимо передать std::unique_ptr<T> по ссылке const, поскольку unique_ptr не может быть скопирован. Также в вашей лямбда-функции нет захватов, поэтому вы можете заменить [&] на [].

Наконец, когда вы хотите использовать std::transform с пустым вектором, вы должны использовать std::back_inserter для добавления к этот вектор. По умолчанию существующие элементы вектора перезаписываются, и, поскольку их нет, вы получите неопределенное поведение. если в вашем интеллектуальном указателе нет управляемого объекта (т.е. если указатель имеет значение NULL).

Вы также должны использовать * не get в вашем компараторе.

...