Exception-safe vector
От: Максим Россия  
Дата: 19.12.22 11:01
Оценка:
Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize, у них он называется "подход с vector_base", с 57:10 про него говорят. Это про то, как обрабатывать ситуацию, когда во время resize удалось выделить новый буфер под данные, но при копировании в него какой-то конструктор копирования бросил исключение и теперь, для всех скопированных элементов надо вызвать деструктор. Никто не сталкивался с таким? И еще вопрос, как вам факт использования try/catch в классе вектора, не режет глаз? Нельзя ли без него как-то обойтись (видимо надо будет использовать RAII обертку)?

https://youtu.be/n5ddGADQIqY?t=3431
Errare humanum est
Re: Exception-safe vector
От: Sm0ke Россия ksi
Дата: 19.12.22 16:35
Оценка: +1
Здравствуйте, Максим, Вы писали:

М>Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize, у них он называется "подход с vector_base", с 57:10 про него говорят. Это про то, как обрабатывать ситуацию, когда во время resize удалось выделить новый буфер под данные, но при копировании в него какой-то конструктор копирования бросил исключение и теперь, для всех скопированных элементов надо вызвать деструктор. Никто не сталкивался с таким? И еще вопрос, как вам факт использования try/catch в классе вектора, не режет глаз? Нельзя ли без него как-то обойтись (видимо надо будет использовать RAII обертку)?


М>https://youtu.be/n5ddGADQIqY?t=3431


Если через конструктор копирования, то можно и через обёртку (без try).

В теле функции объявляем новый вектор. Пошагово копируем и увеличиваем count. При исключении новый вектор удалит только скопированные объекты с валидным count.

Если исключения нет, то:
Потом свапаем impl с this. Новый вектор со старым буфером удалится при выходе из функции как обычная локальная переменная.

А если move конструкторы, то как? Не мувать же их обратно... Или move конструктор элементов должен быть noexcept.
Отредактировано 19.12.2022 16:40 Sm0ke . Предыдущая версия . Еще …
Отредактировано 19.12.2022 16:38 Sm0ke . Предыдущая версия .
Re: Exception-safe vector
От: sergii.p  
Дата: 19.12.22 16:59
Оценка:
Здравствуйте, Максим, Вы писали:

М>Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize


меня больше удивило, что этот подход используется в стандартных реализациях.
Разве что-то типа такого будет оверхедом?

void my_vector::resize(const size_t new_size)
{
    if(needRealloc()) {
        my_vector tmp;
        tmp.reserve(new_size);
        for(const auto& el: *this) {
            tmp.push_back(el);
        }
        std::swap(tmp, *this);
    }
}
Re: Exception-safe vector
От: T4r4sB Россия  
Дата: 19.12.22 18:15
Оценка: +2 -1 :))
Здравствуйте, Максим, Вы писали:

М>Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize, у них он называется "подход с vector_base", с 57:10 про него говорят. Это про то, как обрабатывать ситуацию, когда во время resize удалось выделить новый буфер под данные, но при копировании в него какой-то конструктор копирования бросил исключение и теперь, для всех скопированных элементов надо вызвать деструктор. Никто не сталкивался с таким? И еще вопрос, как вам факт использования try/catch в классе вектора, не режет глаз? Нельзя ли без него как-то обойтись (видимо надо будет использовать RAII обертку)?


Самое дикое, что для всех когда-либо реально используемых мной классов достаточно тупо побитового копирования с удалением старого блока без вызова деструкторов. С++ переусложняет ситуацию на ровном месте
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Exception-safe vector
От: T4r4sB Россия  
Дата: 19.12.22 18:17
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S> Или move конструктор элементов должен быть noexcept.


Как он может быть НЕ noexcept? Не, я в курсе, что конструкции языка такое допускают. Но как такое на практике вообще блин возможно? И как оно должно отрабатывать при исключении?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Exception-safe vector
От: Sm0ke Россия ksi
Дата: 19.12.22 19:48
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Максим, Вы писали:


М>>Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize, у них он называется "подход с vector_base", с 57:10 про него говорят. Это про то, как обрабатывать ситуацию, когда во время resize удалось выделить новый буфер под данные, но при копировании в него какой-то конструктор копирования бросил исключение и теперь, для всех скопированных элементов надо вызвать деструктор. Никто не сталкивался с таким? И еще вопрос, как вам факт использования try/catch в классе вектора, не режет глаз? Нельзя ли без него как-то обойтись (видимо надо будет использовать RAII обертку)?


TB>Самое дикое, что для всех когда-либо реально используемых мной классов достаточно тупо побитового копирования с удалением старого блока без вызова деструкторов. С++ переусложняет ситуацию на ровном месте


Вот по этому люди и велосипедят собственные векторы со своим способом копирования переноса элементов))
Re[2]: Exception-safe vector
От: vsb Казахстан  
Дата: 19.12.22 20:18
Оценка:
Здравствуйте, T4r4sB, Вы писали:

М>>Тут смотрю Mock-интервью по плюсам, в одном из них попросили написать человека класс vector. Заинтересовал подход для реализации метода resize, у них он называется "подход с vector_base", с 57:10 про него говорят. Это про то, как обрабатывать ситуацию, когда во время resize удалось выделить новый буфер под данные, но при копировании в него какой-то конструктор копирования бросил исключение и теперь, для всех скопированных элементов надо вызвать деструктор. Никто не сталкивался с таким? И еще вопрос, как вам факт использования try/catch в классе вектора, не режет глаз? Нельзя ли без него как-то обойтись (видимо надо будет использовать RAII обертку)?


TB>Самое дикое, что для всех когда-либо реально используемых мной классов достаточно тупо побитового копирования с удалением старого блока без вызова деструкторов. С++ переусложняет ситуацию на ровном месте


Как понять побитового копирования? А если класс вида class C { char data[16]; char *data_ptr; };, где data_ptr это указатель на один из элементов data?
Отредактировано 19.12.2022 20:19 vsb . Предыдущая версия . Еще …
Отредактировано 19.12.2022 20:18 vsb . Предыдущая версия .
Re[3]: Exception-safe vector
От: T4r4sB Россия  
Дата: 19.12.22 20:22
Оценка:
Здравствуйте, vsb, Вы писали:

vsb> А если класс вида class C { char data[16]; char *data_ptr; };, где data_ptr это указатель на один из элементов data?


Ты реально таким штукам прописываешь мув-конструктор? Или просто стараешься не гонять по памяти? Типа хранить в юнике на крайнях и всё такое.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[3]: Exception-safe vector
От: Stanislav V. Zudin Россия  
Дата: 19.12.22 20:27
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Как понять побитового копирования? А если класс вида class C { char data[16]; char *data_ptr; };, где data_ptr это указатель на один из элементов data?


Ну если не использовать указатели, перейти на индексы, в массивах хранить POD'ы, то получается запросто.
При правильном применении этот подход даёт ощутимые ништяки.

Но такие структуры применимы не везде.
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: Exception-safe vector
От: Videoman Россия https://hts.tv/
Дата: 19.12.22 22:02
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Самое дикое, что для всех когда-либо реально используемых мной классов достаточно тупо побитового копирования с удалением старого блока без вызова деструкторов. С++ переусложняет ситуацию на ровном месте


Что он переусложняет-то? Он наоборот упрощает. Тебе не нужно думать об этом. Если класс trivially copyable, то: string, vector или любой другой последовательный контейнер, сам будет использовать memcpy и memmove.
Re[2]: Exception-safe vector
От: Максим Россия  
Дата: 20.12.22 07:48
Оценка:
S>А если move конструкторы, то как? Не мувать же их обратно... Или move конструктор элементов должен быть noexcept.
У меня аналогичный вопрос возник...
Можно в теории проверять во время компиляции есть ли у оператора перемещения директива noexcept и если есть, то делать move, а иначе копировать. Но выглядит как-то сложновато.
Errare humanum est
Отредактировано 20.12.2022 7:52 Максим . Предыдущая версия .
Re[2]: Exception-safe vector
От: flаt  
Дата: 20.12.22 07:49
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Самое дикое, что для всех когда-либо реально используемых мной классов достаточно тупо побитового копирования с удалением старого блока без вызова деструкторов. С++ переусложняет ситуацию на ровном месте


Вроде как есть (должны быть) специализации операций над вектором с упрощённой логикой для таких типов.
Re[3]: Exception-safe vector
От: T4r4sB Россия  
Дата: 20.12.22 07:50
Оценка:
Здравствуйте, Videoman, Вы писали:

V> сам будет использовать memcpy и memmove.


Вектор, строка, юник не являются тривиально_копиабельными. Но для них тоже можно делать memcpy и memmove. Ну и где?!
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[3]: Exception-safe vector
От: T4r4sB Россия  
Дата: 20.12.22 08:01
Оценка:
Здравствуйте, flаt, Вы писали:

F>Вроде как есть (должны быть) специализации операций над вектором с упрощённой логикой для таких типов.


Для каких таких? Для строк, юников, деревьев, хеш-таблиц, других векторов — всех их можно побитово копировать. Но вместо этого делается поэлементный мув. Когда изобретут такую оптимизацию?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Exception-safe vector
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.12.22 08:05
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>
 tmp.push_back(el);

Тогда уж tmp.emplace_back(el)
Sic luceat lux!
Re[3]: Exception-safe vector
От: T4r4sB Россия  
Дата: 20.12.22 08:19
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, sergii.p, Вы писали:


SP>>
 tmp.push_back(el);

K>Тогда уж tmp.emplace_back(el)

В данном случае — никакой разницы. По ссылке принимаем аргумент для конструктора копирования, элемент конструируем по месту...
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[3]: Exception-safe vector
От: sergii.p  
Дата: 20.12.22 08:22
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Sm0ke, Вы писали:


S>> Или move конструктор элементов должен быть noexcept.


TB>Как он может быть НЕ noexcept? Не, я в курсе, что конструкции языка такое допускают. Но как такое на практике вообще блин возможно? И как оно должно отрабатывать при исключении?


что здесь удивительного? Разработчик забыл поставить noexcept и получил копирование в векторе. Всё в стиле C++: не доглядел — отстрелил ногу.
Re[4]: Exception-safe vector
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.12.22 08:50
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>что здесь удивительного? Разработчик забыл поставить noexcept и получил копирование в векторе. Всё в стиле C++: не доглядел — отстрелил ногу.

Ну почему отстрелил? Просто не произвёл тонкую настройку .
Sic luceat lux!
Re[4]: Exception-safe vector
От: Videoman Россия https://hts.tv/
Дата: 20.12.22 10:20
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Вектор, строка, юник не являются тривиально_копиабельными. Но для них тоже можно делать memcpy и memmove. Ну и где?!


Что где?! Напиши нормально что ты имеешь в виду. Внутри себя вектор, строка и т.д. и так будут использовать memcpy и memmove, если тип их значения тривиально копируемый. Если ты имеешь в виду вектор векторов, то какой там memcpy
Отредактировано 20.12.2022 10:21 Videoman . Предыдущая версия .
Re[5]: Exception-safe vector
От: T4r4sB Россия  
Дата: 20.12.22 12:14
Оценка: -1
Здравствуйте, Videoman, Вы писали:

V>Здравствуйте, T4r4sB, Вы писали:


TB>>Вектор, строка, юник не являются тривиально_копиабельными. Но для них тоже можно делать memcpy и memmove. Ну и где?!


V>Что где?! Напиши нормально что ты имеешь в виду.


Я и пишу: если у тебя есть вектор, типом элемента которого является вектор строка или юник, то такой вектор имеет право тупо побитово копировать содержимое, а не гонять зря мув-конструкторы.

V>Если ты имеешь в виду вектор векторов, то какой там memcpy


Обычный такой memcpy, в чём проблема?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 20.12.2022 12:15 T4r4sB . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.