Как справиться с отсутствующим emplace_range в C ++ 0x STL? - PullRequest
10 голосов
/ 15 ноября 2010

У меня есть два контейнера, допустим, они определены следующим образом:

std::vector<std::unique_ptr<int>> a;
std::vector<std::unique_ptr<int>> b;

Предположим, заполнены как a, так и b. Я хочу вставить весь контейнер a в определенное место в b, используя семантику перемещения, чтобы unique_ptr s переместился на b. Давайте предположим, что i является действительным итератором где-то в b. Следующее не работает:

b.insert(i, a.begin(), a.end()); // error: tries to copy, not move, unique_ptrs

Есть ли другой алгоритм STL, который может достичь этого «вставка-диапазон-при-движении»? Я думаю, мне нужно что-то вроде emplace_range, но его нет в STL VS2010. Я не хочу писать цикл, который вставляет один за другим, так как это приведет к неприятному O (n ^ 2) из-за смещения всего содержимого вектора при каждом его добавлении. Любые другие варианты?

Ответы [ 3 ]

17 голосов
/ 15 ноября 2010
auto a_begin = std::make_move_iterator(a.begin());
auto a_end = std::make_move_iterator(a.end());

b.insert(i, a_begin, a_end); 
4 голосов
/ 15 ноября 2010

Вы insert необходимое количество пустых элементов в цели (за один выстрел) и затем используете swap_ranges.Исходные элементы в любом случае будут бесполезны, поскольку это unique_ptr.

. Это будет работать для pre-C ++ 0x, но другой ответ явно лучше для Visual C ++ 10..

1 голос
/ 28 января 2011

На самом деле, вы можете использовать старый добрый std::swap_ranges(...)

http://www.cplusplus.com/reference/algorithm/swap_ranges/

...