Учтите следующее:
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_ptr
s)
Если требуется перераспределение, и оно терпит неудачу, тогда да, ваш объект никогда не попадал в контейнер и, следовательно, будет потерян.
Однако следует отметить, что это чисто пользовательская ошибка. emplace_back
не должен быть «забанен» за контейнеры unique_ptr
потому что есть совершенно безопасные способы сделать это (такие как reserve
заранее, так что вы всегда будете там). Также вы можете пройти в целом unique_ptr
с, так как он вполне способен использовать конструктор перемещения.
Так что на самом деле, вы виноваты в том, что неправильно обернули свой объект не-RAII ( int*
) в объекте RAII до точки, в которой вы можете генерировать исключения.
Других решений пока нет …