C++ Embedded

@channel_cppembedded
Теперь представим, что захотелось нам в прошивке микроконтроллера заиметь вектор. Конечно, никакого динамического выделения памяти, только аллокатор! 𝚞𝚜𝚒𝚗𝚐 𝚂𝚞𝚙𝚎𝚛𝚅𝚎𝚌𝚝𝚘𝚛 = 𝚜𝚝𝚍::𝚟𝚎𝚌𝚝𝚘𝚛<𝚒𝚗𝚝, 𝚂𝚒𝚖𝚙𝚕𝚎𝙰𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛<𝚒𝚗𝚝>>; А теперь почему бы не сделать из таких векторов кортеж, чем я хуже губернатора? 𝚞𝚜𝚒𝚐𝚗 𝚂𝚞𝚙𝚎𝚛𝚃𝚞𝚙𝚕𝚎 = 𝚜𝚝𝚍::𝚝𝚞𝚙𝚕𝚎<𝚒𝚗𝚝, 𝚂𝚞𝚙𝚎𝚛𝚅𝚎𝚌𝚝𝚘𝚛, 𝚂𝚞𝚙𝚎𝚛𝚅𝚎𝚌𝚝𝚘𝚛>; Можно такой tuple объявить как обычно 𝚂𝚞𝚙𝚎𝚛𝚃𝚞𝚙𝚕𝚎 𝚝{𝟺𝟸, {𝟷, 𝟸}, {𝟹, 𝟺}}; Но такие обои будут невероятно скучными. Каждому элементу просто выдадут аллокатор SimpleAllocator<int>{} по умолчанию. Можно поступить оригинально и воспользоваться такой конструкцией 𝚂𝚒𝚖𝚙𝚕𝚎𝙰𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛<𝚒𝚗𝚝> 𝚊𝚕𝚕𝚘𝚌{𝟷𝟶𝟶}; 𝚂𝚞𝚙𝚎𝚛𝚃𝚞𝚙𝚕𝚎 𝚝{ 𝚜𝚝𝚍::𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛_𝚊𝚛𝚐, 𝚊𝚕𝚕𝚘𝚌, 𝟺𝟸, {𝟷, 𝟸}, {𝟹, 𝟺} }; Тогда каждому вектору будем передан именно alloc. Другое дело, что хранят объекты аллокаторов в виде копии. Поэтому стандарт требует, чтобы такие объекты копировались легко. Это имеет значение, если у аллокатора есть состояние и при копировании оно не теряется. Я спросил у tuple, как у него получается подсовывать аллокатор только тем элементам, которому он подойдет, а он мне и отвечает, мол, читай пункт 20.2.8 uses_allocator [allocator.uses]. Есть такой trait как 𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎<𝚌𝚕𝚊𝚜𝚜 𝚃, 𝚌𝚕𝚊𝚜𝚜 𝙰𝚕𝚕𝚘𝚌> 𝚜𝚝𝚛𝚞𝚌𝚝 𝚞𝚜𝚎𝚜_𝚊𝚕𝚕𝚘𝚌𝚊𝚝𝚘𝚛; Он автоматически определяет, имеет ли тип T вложенный allocator_type, который можно преобразовать из Alloc. Ну или у него нет вложенного allocator_type, но в конструктор можно впихнуть тэг allocator_arg_t первым элементом, а Alloc вторым, или вообще Alloc это последний аргумент. В общем, возможность интересная. Когда будет колхозить очередной контейнер, обязательно применим.
Если у вас установлено приложение,
вы можете сразу перейти в канал