В C++17 (может уже и в 14-ом) у аллокаторов часть интерфейса объявлена как deprecated.
В С++20 этот deprecated вырезали окончательно.
В частности речь идет про rebind.
У меня в коде есть "raw_memory" allocator. Который сам по себе возвращает void*.
Я его подсовывал в std::vector, std::list ..., они его ребиндили к нужному типу и все прекрасно работало.
При включении C++17 в VS2019, вылазит ошибка компиляции:
Ошибка C2338 vector<T, Allocator> requires that Allocator's value_type match T (See N4659 26.2.1 [container.requirements.general]/16 allocator_type) Either fix the allocator value_type or define _ENFORCE_MATCHING_ALLOCATORS=0 to suppress this diagnostic.
class vector { // varying size array of values
//.... вот эта проверка
static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>,
_MISMATCHED_ALLOCATOR_MESSAGE("vector<T, Allocator>", "T"));
Смысла решать проблему через _ENFORCE_MATCHING_ALLOCATORS я не вижу.
КД>У меня в коде есть "raw_memory" allocator. Который сам по себе возвращает void*.
Вот здесь и возникает вопрос, зачем ты так сделал? Аллокатор — он типизированный. Почему твой value_type не такой, как тот, для которого попросили аллокатор?
КД>Вопрос — это что, если я хочу юзать свои распределяторы памяти, мне с этими костылями до конца жизни жить?
Покажи код своего аллокатора и мы его пофиксим )))
КД>Раньше было лучше!
Это бесспорно.
Здравствуйте, Vamp, Вы писали:
КД>>У меня в коде есть "raw_memory" allocator. Который сам по себе возвращает void*. V>Вот здесь и возникает вопрос, зачем ты так сделал? Аллокатор — он типизированный. Почему твой value_type не такой, как тот, для которого попросили аллокатор?
КД>>Вопрос — это что, если я хочу юзать свои распределяторы памяти, мне с этими костылями до конца жизни жить? V>Покажи код своего аллокатора и мы его пофиксим )))
В контейнеры подсовывается t_void_allocator (стандартная реализация для t_raw_allocator).
Там он ребиндится к нужному типу и возвращает t_allocator_interface.
КД>Вопрос — это что, если я хочу юзать свои распределяторы памяти, мне с этими костылями до конца жизни жить?
Уже можно перейти на std::pmr, и выкинуть все костыли.
Используешь std::pmr::vector<T>, std::pmr::map<K, V> и т.д. , которые синонимы для std::vector<T, std::polymorphic_allocator<T>>, std::vector<T, std::polymorphic_allocator<std::pait<const K, V>>>, и т.д.
Подсовываешь им параметром наследника std::pmr::memory_resource, в котором нужно переопределить три виртуальные функции:
распределение через your_memory_resource попадёт не только в объемлющий контейнер, но и в оба вложенных.
Т.е. если в your_memory_resource сделан какой-то кастомный пул,требующий контекста, то контекст сам пропагейтится.
Здравствуйте, Alexander G, Вы писали:
КД>>Вопрос — это что, если я хочу юзать свои распределяторы памяти, мне с этими костылями до конца жизни жить?
AG>Уже можно перейти на std::pmr, и выкинуть все костыли.
Штука интересная, но не все сразу
-- Пользователи не приняли программу. Всех пришлось уничтожить. --