Я пытаюсь реализовать уникальный_ресурс из предложения p0052r2.
http://www.open -std.org / jtc1 / sc22 / wg21 / docs /apers / 2016 / p0052r2.pdf
Объявление конструктора из предложения:
unique_resource(unique_resource&& rhs)
noexcept(is_nothrow_move_constructible_v<R> &&
is_nothrow_move_constructible_v<D>);
, где R - ресурс, а D - удалитель.
Поведение описывается следующим образом:
Если is_nothrow_move_constructible_v имеет значение true, инициализировать ресурс из forward (rhs.resource), в противном случае инициализировать ресурс из rhs.resource. [Примечание.time.— end note] Затем, если is_nothrow_move_constructible_v имеет значение true, инициализировать удалитель вперед (rhs.deleter), в противном случае инициализировать удалитель из rhs.deleter.Если конструкция удалителя создает исключение: если! Is_nothrow_move_constructible_v, то rhs.deleter (resource).
У меня есть два вопроса по этому поводу.
Почему следуетЯ инициализирую, используя forward (rhs.resource) или rhs.resource вместо std :: move (rhs.resource).То же самое для D.
Как правильно реализовать обработку исключений?
Только если выдает конструктор удалителя, я должен освободитьresource.
В настоящее время у меня есть:
CUniqueResource(CUniqueResource&& rhs) try
: executeOnDestruction(rhs.executeOnDestruction)
, resource(std::move(rhs.resource))
, deleter(std::move(rhs.deleter))
{
rhs.release();
}
catch (...)
{
if constexpr(!std::is_nothrow_move_constructible_v<R>)
{
rhs.deleter(resource);
}
throw;
}
Проблема состоит в том, что блок try функции также включает конструирование ресурса.Что я могу сделать, чтобы перехватывать только исключения для средства удаления, не вводя вызов конструктору по умолчанию средства удаления.
Редактировать:
Мне кажется, я нашел ответ на второйвопрос основан на комментариях eerorika.Функция-член используется вместо подобъекта.
Код выглядит следующим образом:
CUniqueResource(CUniqueResource&& rhs)
: executeOnDestruction(rhs.executeOnDestruction)
, resource(std::move(rhs.resource))
, deleter(acquireDeleter(rhs))
{
rhs.release();
}
D acquireDeleter(CUniqueResource&& rhs)
{
try
{
return D(std::move(rhs.deleter));
}
catch(...)
{
if constexpr(!std::is_nothrow_move_constructible_v<R>)
{
rhs.deleter(this->resource);
}
throw;
}
}
Я думаю, что это должно работать, потому что C ++ гарантирует отмену копирования для возвращаемого значения.