Доступ к unique_ptrs в std vector - должен предоставить конструктор копирования? - PullRequest
1 голос
/ 10 июня 2019

Я создал вектор std и сдвинул на него кучу объектов, используя ход std, например:

vector<unique_ptr<Foo> > myVec;
unique_ptr<Foo> a = make_unique<Foo>();
unique_ptr<Foo> b = make_unique<Foo>();
myVec.push_back(move(a));
myVec.push_back(move(b));

Пока все хорошо.

ПозжеЯ передаю ссылку на myVec в функцию и пытаюсь получить доступ к данным в векторе, используя [] -операторы.

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    Foo* anObj = myVec[0];
}

После некоторого прочтения я предполагаю, что этот подход не будет работатьпотому что вектор std будет пытаться сделать копию, и если я не предоставлю конструктор копирования на Foo, который позволит избежать создания копии, он никогда не будет работать.Я прав?Я думаю, что я видел некоторые посты об использовании итераторов, но я бы предпочел не делать этого.

EDIT1:

Мне удалось обойти это следующим образом (используя итератор изатем получить необработанный указатель)

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    int offset = 0; // Or some other offset into the vector
    auto it = myVec.begin() + offset;
    Foo* anObj = it.get();
    // ... Do something using anObj here...
}

Я думаю, что это правильный путь, если вы не пытаетесь глупо сохранить anObj, а затем освободить его где-нибудь вручную.Конечно, я мог бы временно передать право собственности, пока я не покончу с этим, а затем вернуть право собственности, но это похоже на такую ​​стычку.Есть мысли по поводу вышеуказанного подхода?

Заранее спасибо, / Джимми

Ответы [ 2 ]

3 голосов
/ 10 июня 2019

Переменная anObj должна иметь тип std::unique_ptr<Foo>, а не Foo*.

Код должен быть:

std::unique_ptr<Foo>& anObj{ myVec[ 0 ] };

Или

Foo* anObj{ myVec[ 0 ].get( ) };

0 голосов
/ 10 июня 2019

C ++ не решит за вас, если используете копирование или справочное присвоение.

Ты должен справиться с этим сам.

  • Если вы объявляете новую переменную и используете оператор = в строке объявления, например int y = x;, вы используете конструктор копирования.
  • Если вы объявите переменную с & перед ней, например int & y = x; вы берете ссылку на x и сохраняете ее в y.

В вашем примере у вас есть 2 проблемы:

  1. Вы пытаетесь присвоить unique_ptr<Foo> Foo*, что неверен.
  2. Вы хотите иметь ссылку unique_ptr<Foo>, чтобы вы должен объявить unique_ptr<Foo> ссылку следующим образом: unique_ptr<Foo> & ref = myVec[0];
...