В C++11 появилась новая система распределения. Он обратно совместим из-за слабых требований к распределителям в старом стандарте, но может потребоваться некоторые изменения для распределителей, которые работали со старыми версиями неупорядоченных контейнеров. Использует класс признаковallocator_traits
для обработки распределителя, добавляющего дополнительную функциональность и делающего некоторые методы и типы необязательными. При разработке стабильного выпускаallocator_traits
не было доступно, поэтому в этой версии всегда используется внутренняя частичная реализация. Будем надеяться, что будущая версия будет использовать стандартную реализацию.
Функции-членыконструируют
,разрушают
иmax_size
теперь являются необязательными, если они недоступны, используется запасной вариант. Полная реализациячерт распределителя
требует сложного обнаружения функции члена, так что запасной вариант используется всякий раз, когда вызов функции члена плохо сформирован. Для этого требуется поддержка выражений SFINAE, которые доступны на GCC из версий 4.4 и Clang.
На других компиляторах есть только тест, чтобы увидеть, есть ли у распределителя член, но нет проверки, что его можно назвать. Поэтому вместо использования резервного копирования будет просто ошибка компиляции.
propagate_on_container_copy_assignment
,propagate_on_container_move_assignment
,propagate_on_container_swap
иselect_on_container_copy_construction
также поддерживаются. Из-за несовершенной эмуляции движения некоторые назначения могут проверятьраспространение_on_container_copy_assignment
на некоторых компиляторах ираспространение_on_container_move_assignment
на других.
Использование методов построения и разрушения распределителя может быть немного удивительным. Узлы строятся и разрушаются с помощью распределителя, но элементы хранятся в выровненном пространстве внутри узла и строятся и разрушаются путем вызова конструктора и деструктора напрямую.
В C++11 функция построения распределителя имеет подпись:
template <class U, class... Args>
void construct(U* p, Args&&... args);
(52)для содержащегося объекта, но большинство существующих распределителей не поддерживают это. Если обнаружение функции члена было достаточно хорошим, то со старыми распределителями оно возвращалось бы к вызову конструктора элемента напрямую, но в целом обнаружение недостаточно хорошо для этого. Неупорядоченный просто звонит конструктору каждый раз. В большинстве случаев это будет работать нормально.
указательные черты
не используются. Вместо этого, типы указателей получают из распределителей отскока, это может вызвать проблемы, если распределитель не может быть использован с неполными типами. Еслиconst_pointer
не определен в распределителе,boost::pointer_to_other<pointer,constvalue_type>::type
используется для получения const pointer.
Поскольку контейнеры используютstd::пара
, они ограничены версией из текущей стандартной библиотеки. Но поскольку C++11std::pair
piecewise_construct
Based constructor очень полезен,Emplace
эмулирует егоpiecewise_construct
вboost:неупорядоченное
пространство имен. Так, например, будет работать следующее:
boost::unordered_multimap<std::string, std::complex> x;
x.emplace(
boost::unordered::piecewise_construct,
boost::make_tuple("key"), boost::make_tuple(1, 2));
Старые проекты стандарта также поддерживали вариадные конструкторы дляstd::пары
, где первый аргумент будет использоваться для первой части пары, а оставшийся для второй части.
При заменеPred
иHash
в настоящее время не заменяются вызовомswap
, используются их конструкторы копий. Как следствие, при замене исключения могут быть выброшены из их конструктора копий.
Аргументы вариадного конструктора дляместа
используются только тогда, когда доступны как ссылки на значение r, так и параметры вариадных шаблонов. В противном случаеместо
может принимать только до 10 аргументов конструкторов.