Перебор контейнера уникальных ptr-файлов



Как получить доступ к элементам unique_ptr контейнера (через итератор), не забирая права собственности у контейнера? Когда вы получаете итератор к элементу в контейнере, является ли владение элементом все еще с контейнером? Как насчет разыменования итератора для получения доступа к unique_ptr? Выполняет ли это неявное перемещение unique_ptr?



Я обнаружил, что часто использую shared_ptr, когда мне нужно хранить элементы в контейнере (не по значению), даже если container концептуально владеет элементами, а другой код просто хочет манипулировать элементами в контейнере, потому что я боюсь, что не смогу фактически получить доступ к элементам unique_ptr в контейнере без права собственности на него.



Какие-нибудь идеи?

749   2  

2 ответов:

Пока вы не пытаетесь сделать копию unique_ptr, Вы можете просто использовать ее. Вам придется "дважды разыменовать" итератор, чтобы добраться до значения указателя, точно так же, как и с shared_ptr. Вот краткий пример:

#include <vector>
#include <memory>
#include <iostream>

template <class C>
void
display(const C& c)
{
    std::cout << '{';
    if (!c.empty())
        std::cout << *c.front();
    for (auto i = std::next(c.begin()); i != c.end(); ++i)
        std::cout << ", " << **i;
    std::cout << "}\n";
}

int main()
{
    typedef std::unique_ptr<int> Ptr;
    std::vector<Ptr> v;
    for (int i = 1; i <= 5; ++i)
        v.push_back(Ptr(new int(i)));
    display(v);
    for (auto i = v.begin(); i != v.end(); ++i)
        **i += 2;
    display(v);
}

Если вы (случайно) сделаете копию unique_ptr:

Ptr p = v[0];

Тогда вы узнаете об этом во время компиляции. Это не вызовет ошибки во время выполнения. Ваш пример использования-это то, почему был построен container<unique_ptr<T>>. Вещи должны просто работать, а если они этого не делают, проблема появляется на время компиляции вместо времени выполнения. Так что код прочь, и если вы не понимаете ошибку времени компиляции, тогда задайте еще один вопрос здесь.

С auto и основанными на диапазоне циклами для C++11 это становится относительно элегантным:

std::vector< std::unique_ptr< YourClass >> pointers;
for( auto&& pointer : pointers ) {
    pointer->functionOfYourClass();
}

Ссылка & на std::unique_ptr позволяет избежать копирования, и вы можете использовать uniqe_ptr без разыменования.

Comments

    Ничего не найдено.