Могу ли я переслать конструкцию в теле конструктора? - PullRequest
0 голосов
/ 21 сентября 2018

Давайте рассмотрим, что во время выполнения конструктора класса S оказывается, что S может быть создан с использованием другого конструктора.Одним из решений может быть создание нового размещения на this для повторного использования хранилища:

struct S{
    unsigned int j; //no const neither reference non static members
    S(unsigned int i){/*...*/}
    S(int i){
       if (i>=0) {
         new (this) S(static_cast<unsigned int>(i));
         return;}
       /*...*/
       }
    };
 int i=10;
 S x{i};//is it UB?

Повторное использование хранилища определено в [basic.life] .Я не знаю, как читать этот раздел, когда хранилище (пере) используется во время выполнения конструктора.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Стандарт полностью не указан в этом случае, и я не могу найти соответствующую проблему CWG.

Само по себе ваше новое размещение не UB.В конце концов, у вас есть хранилище без объекта, поэтому вы можете напрямую создать в нем объект.Как вы правильно сказали, время жизни первого объекта еще не началось.

Но теперь проблема в том, что происходит с исходным объектом?Потому что обычно конструктор вызывается только в хранилище без объекта, а конец конструктора отмечает начало времени жизни объекта.Но сейчас уже есть другой объект.Новый объект уничтожен?Это не имеет никакого эффекта?

В стандарте отсутствует абзац в [class.cdtor], в котором говорится, что должно произойти, если новый объект создается в хранилище строящегося и уничтожаемого объекта.

Вы можете даже построить еще более странный код:

struct X {
  X *object;
  int var;
  X() : object(new (this) X(4)), var(5) {} // ?!?
  X(int x) : var(x) {}
} x;
0 голосов
/ 21 сентября 2018

это UB?

Нет, это не так.[basic.life]/5 говорит:

Программа может завершить время жизни любого объекта, повторно используя хранилище, которое объект занимает , или явно вызывая деструктор для объекта типа классас нетривиальным деструктором.Для объекта типа класса с нетривиальным деструктором, программе не требуется явно вызывать деструктор до повторного использования или освобождения хранилища, которое занимает объект;однако, если нет явного вызова деструктора или если выражение delete не используется для освобождения хранилища, деструктор не должен вызываться неявно, и любая программа, которая зависит от побочных эффектов, создаваемых деструктором, имеет неопределенное поведение.

Акцент на части, относящейся к вашему классу, которая имеет тривиальный деструктор.Что касается конкретной формы new (this) T;, я не нашел исключения из этого правила ни в [class.cdtor], ни в [class.dtor].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...