std::allocator_arg
Выверенность стандарта всегда восхищает любого грамотного разработчика. Даже питониста. Вайбкодера не восхищает, они не умеют читать. Только писать.
В стандарте продумано все. Даже костыли.
Костылями, в хорошем смысле слова, можно назвать структуры-теги, разрешающие неоднозначности в конструкторах контейнеров.
Недавно перечитывал избранные места в стандарте и наткнулся на описание пустой структуры allocator_arg_t. Ее название намекало на тесную связь с аллокаторами.
"Это в деле embedded вещь полезная, надо посмотреть, кто и зачем эту штуку использует", - подумал я.
Интересно, что одно из первых упоминаний данного объекта встречается еще в древних трактатах, написанных чуть позже ипаатьевской леетописи, в 2008 году: предложение N2554 The Scoped Allocator Model (Rev 2) опубликованным Pablo Halpern.
Автор в порыве новаторства проповедовал:
А давайте присобачим специальные конструкторы к типам вроде pair, tuple и function. Тогда сможем создавать эти контейнеры с использованием аллокаторов, если в них будут элементы, которые такие аллокаторы принимают.Однако, чтобы не мешать вариативным конструкторам, мы аллокаторы будем передавать вначале и для надежности поставим первым специальный тип allocator_arg_t, чтобы четко демаркировать мух от котлет. Н
апример, конструктор копирования с аллокатором для типа pair выглядит следующим образом:
𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎 <𝚌𝚕𝚊𝚜𝚜 𝙰𝚕𝚕𝚘𝚌>
𝚙𝚊𝚒𝚛(𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐_𝚝, 𝚌𝚘𝚗𝚜𝚝 𝙰𝚕𝚕𝚘𝚌&, 𝚌𝚘𝚗𝚜𝚝 𝚙𝚊𝚒𝚛&);
Как вы понимаете, эту наркоманию в pair прикрыли быстро. Хотя были слухи, что конструктор pair с аллокатором таки засветился в черновиках стандарта.
Забавно, что наш старый знакомый Pablo Halpern через год - в 2009 году - публикует еще одно предложение N2945 с красноречивым заголовком Proposal to Simplify pair.
Мол, натворили мы с вами делов. Было у pair три конструктора, а стало 14! Давайте все уберем по-тихому, все же pair не совсем контейнер. Эта струкрута должна быть максимально простой. Тем не менее, идея никуда не делась, и по сей день есть в стандарте, в 20.2.7 Allocator argument tag [allocator.tag]:
𝚗𝚊𝚖𝚎𝚜𝚙𝚊𝚌𝚎 𝚜𝚝𝚍 {
𝚜𝚝𝚛𝚞𝚌𝚝 𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐_𝚝 { 𝚎𝚡𝚙𝚕𝚒𝚌𝚒𝚝 𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐_𝚝() = 𝚍𝚎𝚏𝚊𝚞𝚕𝚝; };
𝚒𝚗𝚕𝚒𝚗𝚎 𝚌𝚘𝚗𝚜𝚝𝚎𝚡𝚙𝚛 𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐_𝚝 𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐{};
}
Официально, структура allocator_arg_t - это пустой тип класса, используемый в качестве уникального типа для различения перегрузки конструкторов и функций.
Его использует, например, tuple.