Значение `std:: make_shared <POD>()` инициализирует мой POD?
Значит ли значение std::make_shared<POD>()
инициализировать мой POD?
Если да, это гарантировано стандартом?
Если нет (как я подозреваю), есть ли способ сделать это? Я думаю, std::make_shared<POD>(POD())
будет делать, но это то, что я должен делать?
Ответы
Ответ 1
Да, это значение инициализируется, и это гарантируется стандартом:
§20.7.2.2.6,2: (около make_shared
)
Эффекты: выделяет память, подходящую для объекта типа T
, и создает объект в этой памяти через новое выражение размещения ::new (pv) T(std::forward<Args>(args)...)
.
И §5.3.4,15:
Новое выражение, создающее объект типа T, инициализирует этот объект следующим образом: - Если новый инициализатор опущен, объект инициализируется по умолчанию (8.5); если инициализация не выполняется, объект имеет неопределенное значение.
- В противном случае новый-инициализатор интерпретируется в соответствии с правилами инициализации 8.5 для directinitialization.
Итак, он прямо инициализирован как в new POD()
.
§8.5,16:
Семантика инициализаторов такова. [...]
- Если инициализатор равен(), , объект инициализируется значением.
Ответ 2
Значение std::make_shared<POD>()
инициализирует мой POD?
Да.
Если да, это гарантировано стандартом?
С++ 11 20.7.2.2.6/2 указывает, что он "создает объект в этой памяти
через размещение нового выражения ::new (pv) T(std::forward<Args>(args)...)
". Без аргументов это будет ::new (pv) T()
, значение которого инициализирует объект.
Ответ 3
Значение std::make_shared<POD>()
инициализирует мой POD?
Да, это так. В пункте 20.7.2.2.6/2 о std::make_shared<>()
говорится, что:
2 Эффекты: выделяет память, подходящую для объекта типа T
, и создает объект в этой памяти через размещение new
выражение ::new (pv) T(std::forward<Args>(args)...)
.
Если аргументы не переданы, это означает, что ваша структура данных построена следующим образом:
::new(pv) T()
Это гарантированно даст прямую инициализацию из-за пункта 5.3.4/15:
Новое выражение, создающее объект типа T
, инициализирует этот объект следующим образом:
- Если новый инициализатор опущен, объект инициализируется по умолчанию (8.5); если инициализация не выполняется, объект имеет неопределенное значение.
- В противном случае новый-инициализатор интерпретируется в соответствии с правилами инициализации 8.5 для прямой инициализации.
В вашем случае присутствует новый инициализатор и ()
. И прямая инициализация с пустым набором круглых скобок указана для получения инициализации значения в пункте 8.5/11:
Объектом, инициализатором которого является пустой набор скобок, т.е. ()
, должен быть инициализирован значением. [...]