Разрешено ли создавать элементы данных структуры отдельно? - PullRequest
2 голосов
/ 09 ноября 2019
class A;
class B;
//we have void *p pointing to enough free memory initially
std::pair<A,B> *pp=static_cast<std::pair<A,B> *>(p);
new (&pp->first) A(/*...*/);
new (&pp->second) B(/*...*/);

После выполнения приведенного выше кода гарантированно ли *pp будет в допустимом состоянии? Я знаю, что ответ верен для каждого протестированного мной компилятора, но вопрос в том, является ли это законным в соответствии со стандартом и, следовательно, таким образом. Кроме того, есть ли другой способ получить такой pair, если A или B не является подвижным в C ++ 98/03? (благодаря @ StoryTeller-UnslanderMonica, есть кусочный конструктор для std::pair начиная с C ++ 11)

Ответы [ 2 ]

4 голосов
/ 10 ноября 2019

«Доступ» к членам несуществующего объекта pair является неопределенным поведением согласно [basic.life] / 5;pair никогда не является POD-классом (имеющим объявленные пользователем конструкторы), поэтому указатель на его хранение вне срока службы не может использоваться для его членов. Не ясно, является ли формирование указателя на член уже неопределенным, или если new имеет значение.

Также нет способа создать пару не копируемых (не movable конечно же, типы в C ++ 98 - вот почему был добавлен кусочный конструктор вместе с семантикой перемещения.

0 голосов
/ 10 ноября 2019

Более простой вопрос: правильно ли используется литеральная строка?

Даже не потому, что ее время жизни не определено. Вы не можете использовать строковый литерал в соответствующем коде.

Таким образом, комитет, который никогда не занимал время, чтобы четко определить строковые литералы, очевидно, не удосужился указать , который могут объекты типа класса. стать существующим путем размещения новых его подобъектов - очевидно, что полиморфные объекты не могут быть созданы таким образом!

Этот стандарт даже не удосужился описать семантику объединения.

Что касается жизни, то стандарт повсеместен, и это не просто редакционная статья: он отражает глубокое разногласие между серьезными людьми о том, что начинает жизнь, что такое объект, что такое lvalue и т. Д.

Примечательно, что люди имеют всевозможные ложные или противоречивые интуиции:

  • бесконечное количество объектов не может быть создано одним вызовом malloc
  • , lvalue ссылается на объект
  • перекрывающиеся объекты относятся к объектной модели
  • безымянный объект может быть создан только new или компиляциейэ-э (временные) ...
...