Исключительная безопасность make_unique: почему безопасно исключение f (new T)

Я читал GOTW102, и удивляюсь, почему make_unique безопаснее исключения, чем другие случаи, или подробно, почему f(new T(...)) безопаснее исключения, чем f(new T1(...), new T2(...)),

make_unique Реализация из блога гласит:

template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}

Теперь мне интересно, если f(new T(...)) как правило, безопасен для исключений (без утечек), или если он является безопасным только для исключений в случае make_unique из-за дополнительных знаний, что конструктор std::unique_ptr не бросает? (Так как если бы это был недавно построенный T будет протекать в любом случае в соответствии с моим пониманием.

2

Решение

Причина в том, что при вызове функции или подобном аргументы не вызывают точки последовательности (не «секвенируются раньше»). Например:

do_work(unique_ptr<A>(new A), unique_ptr<B>(new B));

Компилятору разрешено генерировать код, который выглядит следующим образом:

  1. new A
  2. new B // может бросить!
  3. сооружать unique_ptr<A>
  4. сооружать unique_ptr<B>
  5. Вызов do_work

Если new B бросает, то вы слили A, потому что нет unique_ptr был когда-либо построен.

Ввод unique_ptr конструирование в свою собственную функцию устраняет эту проблему, потому что компиляторам не разрешается выполнять тела функций одновременно (таким образом, конструкции «new» и » unique_ptr шаги должны быть сделаны вместе).


То есть дано:

do_work(make_unique<A>(), make_unique<B>())

Компилятор должен генерировать код, который выглядит следующим образом:

  1. Вызов make_unique<A>
  2. Вызов make_unique<B>
  3. Вызов do_work

или же

  1. Вызов make_unique<B>
  2. Вызов make_unique<A>
  3. Вызов do_work

утечка, где есть новые объекты, плавающие вокруг без владения unique_ptrне возможно

10

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector