В продолжение к this question, Распределитель по умолчанию (std::allocator<T>
) требуется для реализации construct
следующим образом (в соответствии с [default.allocator]):Должен ли allocator construct() инициализировать по умолчанию вместо инициализации значения?
template <class U, class... Args> void construct(U* p, Args&&... args);
Эффекты:
::new((void *)p) U(std::forward<Args>(args)...)
То есть всегда инициализация значений. Результатом этого является то, что std::vector<POD> v(num)
, для любого типа подкачки, будет стоить-инициализировать элементы num
, что является более дорогостоящим, чем инициализация по умолчанию num
элементов.
Почему не & dagger;std::allocator
обеспечивают дополнительную перезагрузку по умолчанию? То есть, что-то вроде (заимствованное из Casey):
template <class U>
void construct(U* p) noexcept(std::is_nothrow_default_constructible<U>::value)
{
::new(static_cast<void*>(p)) U;
}
Была ли причина предпочесть инициализации значения в случаях вызова? Мне кажется удивительным, что это нарушает обычные правила C++, где мы платим только за то, что хотим использовать.
& dagger; Я предполагаю, что такое изменение невозможно в будущем, учитывая, что в настоящее время std::vector<int> v(100)
предоставит вам 100 0
, но мне интересно, почему это так ... учитывая, что так же легко потребовалось бы std::vector<int> v2(100, 0)
так же, как существуют различия между new int[100]
и new int[100]{}
.
См. [P0040] (http: //www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0040r3.html). – FrankHB
@FrankHB Изменит ли этот документ какой бы «вектор» здесь? Это просто добавляет алгоритмы в стандартную библиотеку? – Barry
Право. Так что это не ответ, просто комментарий. Он обеспечивает удобный интерфейс для облегчения реализации вашего обходного пути. – FrankHB