Документация STL гласит, что (1) uninitialized_default_construct
вызывает ::new (static_cast<void*>(std::addressof(*p))) Value;
.
Единственная разница с (2) uninitialized_value_construct
заключается в том, чтопоследующие звонки ::new (static_cast<void*>(std::addressof(*p))) Value();
. (обратите внимание на ()
)
Интересно, в чем практическая разница как для встроенных, так и для нетривиальных типов.
Для встроенных модулей мне кажется, что second (2) выполнит инициализацию значения, т.е. установит значение в ноль, а first (1) будет неактивным (оставляя значение неинициализированным.)
Для нетривиальных типов (2) будем вызывать конструкторы по умолчанию. Что мне не понятно, так это то, что (1) будет делать для нетривиальных типов. Также вызовет конструктор по умолчанию? будет ли он также неактивным, пока T::T() = default
, и он неактивен и оставит элемент в частично сформированном состоянии, если класс был спроектирован таким образом?
Что такжеменя смущает то, что контейнеры STL всегда будут использовать uninitialized_value_construct
, хотя было бы более последовательным вызывать uninitialized_default_construct
, когда это возможно.
Например, std::vector<double>(100)
-> должен вызывать uninitialized_default_construct
, в то время кактекущее поведение могло быть имитировано с помощью std::vector<double>(100, {})
или std::vector<double>(100, double{})
.
Это потому, что концепция uninitialized_default_construct
не существовала в начальной версии STL? или просто нет простого способа передать информацию в конструктор контейнера?