я все равно не понимаю, что происходит, да и в любом случае какое-то ненормальное замедление.
ну логика как будто хочет сказать что да, не распространяется Но ответа я не знаю
https://en.cppreference.com/w/cpp/container/vector/reserve Раздел notes: Correctly using reserve() can prevent unnecessary reallocations, but inappropriate uses of reserve() (for instance, calling it before every push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and result in increased computational complexity and decreased performance. For example, a function that receives an arbitrary vector by reference and appends elements to it should usually not call reserve() on the vector, since it does not know of the vector's usage characteristics.
Думаю, можно утверждать, что точно не распространяется. Сколько просите в резёрве, столько и будет капасити (при увеличении).
Тогда использование reserve может быть антипаттерном, интересно
Нет серебряной пули, конечно :)
неправильное использование*
Я уже некоторое время назад задумывался над тем, что нужна перегрузка reserve, использующая экспоненциальную стратегию расширения. Может быть даже стоит предложить Антону.
А какое поведение? Если текущее капасити C, а reserve на C+x, то делать резёрв на kC, где k такое, чтобы (k-1)C<C+x≤kC?
максимально вредное поведение имхо
Я бы предложил max(requested, current*k).
Поддерживаю
Не дефолт, перегрузка.
Где k это стандартное 2?
А какой юз-кейс будет у данной перегрузки? Я пока его не вижу. reserve как раз таки используется тогда, когда известно сколько должно быть элементов в векторе, и в этом случае экспоненциальный рост не нужен точно. А если уж кто-то зачем-то хочет сделать reserve с экспоненциальным ростом, то ему скорее всего нужен не reserve, а push_back или range insert.
Exception safety: for unknown numer of iterations { v.reserve(v.size()+1); auto x = throwing_function(); // nothrow part v.push_back(x); }
а зачем нам небросающий v.push_back(x), если у нас v.reserve бросит вместо него исключение?
Чтобы вынести бросающий код из цикла например
Как в общем случае пишется exception safe code? В начале выполняются все опасные операции, но результаты сохраняются только локально. И только когда все бросающие функции отработали успешно, фиксируем результат в выходных данных. Грубо говоря идея в том, что откат транзакции должен быть пустой операцией: тогда не нужно писать catch и явно обрабатывать исключения.
Basic guarantee: v.reserve(v.size()+1); auto x = throwing_function(); v.push_back(x); Strong guarantee: v.push_back(throwing_function()); А если у нас 'unknown number of iterations', то здесь ведь только basic получится (если v — инъектированная зависимость). А если мы с откатами хотим поменять v, то тогда уж copy-and-swap. Разделять push_back на reserve (с unlikely бранчем) + push_back имеет смысл только, если мы хотим сэкономить 1 вызов throwing_function после бросания исключения аллокатором.
> Strong guarantee: > v.push_back(throwing_function()); Здесь вы предполагаете что throwing_function можно откатить и что x реализует raii, а там может быть например отправка данных по сети.
Обсуждают сегодня