Предположим, что у меня есть следующий код:
class B { /* */ };
class A {
vector<B*> vb;
public:
void add(B* b) { vb.push_back(b); }
};
int main() {
A a;
B* b(new B());
a.add(b);
}
Предположим, что в этом случае все необработанные указатели B*
можно обрабатывать через unique_ptr<B>
.
Удивительно, но я не смог найти способ преобразования этого кода с помощью unique_ptr
. После нескольких попыток я придумал следующий код, который компилируется:
class A {
vector<unique_ptr<B>> vb;
public:
void add(unique_ptr<B> b) { vb.push_back(move(b)); }
};
int main() {
A a;
unique_ptr<B> b(new B());
a.add(move(b));
}
Итак, мой простой вопрос: это способ сделать это и, в частности, является move(b)
единственным способом сделать это? (Я думал о ссылках на rvalue, но я не совсем понимаю их.)
И если у вас есть ссылка с полными объяснениями семантики перемещения, unique_ptr
и т.д., которые я не смог найти, не стесняйтесь поделиться ею.
EDIT Согласно http://thbecker.net/articles/rvalue_references/section_01.html, мой код выглядит нормально.
Собственно, std:: move - это просто синтаксический сахар. С объектом x класса X move(x)
является таким же, как:
static_cast <X&&>(x)
Эти 2 функции перемещения необходимы, поскольку кастинг на ссылку rvalue:
- запрещает функции "добавлять" от передачи по значению
- делает
push_back
использование конструктора перемещения по умолчанию для B
По-видимому, мне не нужен второй std::move
в моем main()
, если я изменю свою функцию "добавить" для передачи по ссылке (обычный lvalue ref).
Я хотел бы получить некоторое подтверждение всего этого, хотя...