Безопасно ли использовать emplace_back с контейнером unique_ptrs?

Учтите следующее:

std::vector<std::unique_ptr<int>> ptrsToInts;
ptrsToInts.emplace_back(new int);

Если перераспределение происходит в векторе, и это не удается (бросая std::bad_alloc), я «в безопасности», или я буду пропускать int?

C ++ 11 23.3.6.5 [vector.modifiers] / 1 говорит:

Если исключение выдается не конструктором копирования, а конструктором перемещения, оператором присваивания или оператором присваивания перемещения T или любым InputIterator операции нет никаких эффектов.

который, кажется, указывает на то, что это потенциальная проблема. То есть, если нет «никаких эффектов», то нет unique_ptr когда-либо был построен, и, следовательно, поведение деструктора, на которое можно положиться delete этот указатель не произойдет. (Что может означать, что emplace_back должны быть запрещены для контейнеров unique_ptrs)

20

Решение

Если требуется перераспределение, и оно терпит неудачу, тогда да, ваш объект никогда не попадал в контейнер и, следовательно, будет потерян.

Однако следует отметить, что это чисто пользовательская ошибка. emplace_back не должен быть «забанен» за контейнеры unique_ptrпотому что есть совершенно безопасные способы сделать это (такие как reserveзаранее, так что вы всегда будете там). Также вы можете пройти в целом unique_ptrс, так как он вполне способен использовать конструктор перемещения.

Так что на самом деле, вы виноваты в том, что неправильно обернули свой объект не-RAII ( int*) в объекте RAII до точки, в которой вы можете генерировать исключения.

19

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]