Значение `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:

Объектом, инициализатором которого является пустой набор скобок, т.е. (), должен быть инициализирован значением. [...]