Если у меня есть что-то вроде:
vector<int> longVector = { ... };
vector<int> newVector;
transform(longVector.begin(), longVector.end(), back_inserter(newVector),
[] (int i) { return i * i; });
Сможет ли STL предварительно выделить место в newVector
перед обработкой и добавлением новых элементов? Я знаю, что это не требование алгоритма, но сможет ли «хорошая» реализация оптимизировать это? Или, в таком случае, я должен предпочесть добавить newVector.reserve(longVector.size());
раньше? Я не обязательно спрашиваю, работает ли каждая реализация stdlib или нет (хотя, если кто-то знает конкретные примеры, это было бы здорово), но больше, возможно ли это вообще (и ожидается), учитывая интерфейс и требования алгоритмов.
Вопрос относится к нескольким алгоритмам STL, transform
, copy
, move
, fill_n
, ... И не только к back_inserter
, но также front_inserter
и inserter
, я полагаю.
РЕДАКТИРОВАТЬ: Для ясности я имею в виду, может ли stdlib предоставлять конкретные реализации, например, transform
, для случая, когда выходной итератор является back_inserter
из vector
, и в этом случае он будет получать доступ к векторному объекту и резервировать достаточно места чтобы сохранить distance
между заданной парой итераторов перед фактическим запуском преобразования.
reserve
твой друг здесь. - person NathanOliver   schedule 25.09.2018back_insert_iterator
просто звонитpush_back
, имхо. - person Angelicos Phosphoros   schedule 25.09.2018O(n^2)
). Так что лучше просто использоватьreserve
, чем это действительно необходимо (не часто). - person Dan M.   schedule 25.09.2018add3(vector&)
добавил 3 элемента в вектор, разумно зарезервировав для них место, то вызов его в цикле привел бы к квадратичному поведению, поскольку емкость вектора не росла бы экспоненциально. То же самое с тем, что вы предлагаете.reserve
небезопасно, и его следует избегать в любом месте, кроме 1) в функции, которая его создала 2) если вы знаете, что после этого он никогда не будет изменен. - person Dan M.   schedule 25.09.2018reserve
наtransform
в начале алгоритма на основе расстояния между итераторами, а не несколько вызовов в цикле. Диспетчеризация тегов будет использоваться для решения во время компиляции, следует ли вызывать этотreserve
. Однако не уверен, почемуreserve
следует считать небезопасным (или более небезопасным, чем, например,push_back
). - person jdehesa   schedule 25.09.2018vector::reserve
разрешено перераспределять. Он может сохранить свою стратегию роста, несмотря на неоднократные обращения кreserve
- person Caleth   schedule 25.09.2018reserve
в том, что он не является частью концепта. Это потребует очень специфической специализации, напримерcopy(RandomAccess, RandomAccess, std::back_inserter<std::vector<T>>)
. Вы можете легко реализовать это; вопрос (который у меня есть) заключается в том, где именно (пространство имен) поставить такую функцию. (Не уверен, что вообще разрешено писатьstd::
). - person alfC   schedule 25.09.2018