Roman
Блин, я дибил. Сохранил указатель на элемент коллекции
Roman
Который инвалидируется при её расширении
Roman
Это конечно печально, придется вместо vector<T> делать vector <shared_ptr<T>> , хотя вектор является unique овнером
Roman
Или есть какой-то более правильный способ?
Roman
Почему вектор не поддерживает move-only типы?
Vsevolod
эм, vector<unique_ptr<T»
Roman
нет, его нельзя расширять
Roman
почему-то
Roman
почему он не может мувнуть их при расширении?
Berkus
кого нелья расширить
Berkus
и как ты умудрился хранить в векторе что-то что оно инвалидировалось?
Roman
Оно не инвалидировалось. Я просто хранил указатель на элемент вектора и он инвалидировался при расширении вектора
Roman
Обычные грабли
Berkus
ну есть простое решение, не храни указатель
Roman
Хранить указатель нужно. Класс дает его другому погонять на время. Причем гарантировано что время жизни пользователя меньше времени жизни объекта в векторе
Roman
В общем переделал на vector<shared_ptr>, всё ок. Хотя по сути мне нужен vector<unique_ptr>
Pavel
deque
Roman
deque
И правда:
push_front, push_back, emplace_front and emplace_back do not invalidate any references to elements of the deque.
Roman
Интересный юзкейс получается: выбор коллекции исходя из invalidation rules :)
Vsevolod
vector<unique_ptr> вполне себе расширяется
Roman
Roman
Такой вопрос. Есть код который выводит лишний мусор в консоль. Как найти то место где это происходит?
Т.е. как называется самая низкоуровневая функция для вывода на которую есть смысл поставить bp
Roman
Похоже это putc
Berkus
write() как ни странно
Roman
Да, я начал с write, выше него putc , дальше уже streams
Roman
Хм нет. printf write не вызывает
Alexander "SonnySlave"
никто не знает либы для создания DJVU на С/С++?
Roman
Roman
Просто emplace_back не дает strong exception safe гарантии если move-ctor throws
Andrei
Roman
Вообще интересная тема получается с deque : если стоимость перемещения объекта высокая, то лучше использвать deque вместо vector если делаешь много push_back?
Andrei
Andrei
получается, если нет жесткого требования хранить все одним кусокм (где-то требуется сырой указатель на данные), то выходит при частых вставках нужен deque. а если вставок нет, то array
Roman
Да, так и есть:
https://baptiste-wicht.com/posts/2017/05/cpp-containers-benchmark-vector-list-deque-plf-colony.html
Roman
Любопытно что list сливает вектору и деку на random insert маленьких объектов
Roman
128 байт, deque всё ещё лучше чем list на random insertion
Pavel
конечно сливает, там BidirectionalIterator
Roman
Ну и что? Всё равно ведь вектор должен O(n) копирований сделать
Roman
Т.е. по сути копировать дешевле чем итерировать по куче
Pavel
rep mov
Igor
если я правильно понял, то там не только итерировать по куче, но ещё и создавать новые маленькие объекты на куче
Igor
а вектор на маленьких объектах просто уложится в кэш, и отработает в мгновение ока
Roman
Igor
я про то, что список на каждом добавлении будет выделять память, а вектор - только когда у него закончится буфер
ну и маленькому вектору маленьких объектов будет быстрее переложить рядом лежащие объекты, чем списку полезть в кучу и там разгребать место
по-крайней мере так я себе это представляю
Roman
Проблема исключительно в стоимости итерации по куче, всё остальное несущественно
Roman
список получит кучу кеш миссов пока дойдет до нужного нода
Roman
rep mov видимо вообще включит какой-нибудь аппаратный префетчер
Berkus
Roman
Беркус, ты тоже в штатах сидишь? Или ночами работаешь?
vladislav
беркус 24/7 по-моему, лол
Berkus
Ioann_
Ну я так или иначе, думаю, что Беркус много работает :)
Roman
Такой вопрос, у меня есть void * на полиморфный объект. Можно ли получить RTTI?
Alexander "SonnySlave"
Roman
Почему так сделано? Что мешает положить rtti в начало объекта для всех полиморфных типов?
Alexander "SonnySlave"
Alexander "SonnySlave"
не читал, но вроде как там есть коммент
Roman
Там не написан ответ на мой вопрос. Но его можно вывести путем дальнейших рассуждений
Roman
Roman
Там приведен пример layout'а объекта в памяти для которого работать не будет
Roman
Однако я пока не смог понять почему раскладывать базовые классы нужно именно таким обрзом
Roman
А всё, понял. Сейчас сформулирую
Roman
Мы хотим чтобы указатель на VTBL был всегда в начале класса.
Например можно раскладывать объекты так:
class derived1 : virtual_base
layout: [VPTR][virtual_base][derived1]
class derived2 : nonvirt_base, derived1
layout: [VPTR][nonvirt_base][virtual_base][derived1][derived2]
Проблема в том что теперь нельзя создать указатель derived1* на объект derived2
Можно её решить путём дублирования указателя на VTBL:
layout: [VPTR][nonvirt_base][VPTR][virtual_base][derived1][derived2]
Но это overhead который будет накапливаться по мере разрастания иерархии типов
Roman
В общем это плата за множественное наследование
Thorn
а вот почему бы не ввести в c++ java-подобные интерфейсы (они даже в аде есть, где нет классов в традиционном понимании) и не deprecate множественное наследование от классов?
Roman
Java-подобные интерфейсы уже есть
Roman
public virtual метод
Roman
Но чтобы люди перестали пользоваться множественным наследованием неплохо бы сделать делегирование в языке
Roman
Просто сейчас компактнее кодить с множественным наследованием, чем с интерфейсами и композицией
Thorn
Java-подобные интерфейсы уже есть
ну это классический вопрос с собеседования: "чем абстрактный класс отличается от интерфейса". вот первые в с++ есть, вторых нет
Roman
Чем отличается абстрактный класс с public pure virtual методами и без data members от интерфейсов?
Andrei
pure*
Roman
Andrei
Ничем, кажется.