Переместить объекты из неупорядоченного ассоциативного контейнера - PullRequest
2 голосов
/ 31 мая 2011

Есть ли способ в c ++ 0x перемещать объекты из неупорядоченных ассоциативных контейнеров? Мне нужно объединить два отдельных неупорядоченных набора, и я хотел бы, в случае использования rvalues, «перерабатывать» элементы в наборах, которые скоро будут прекращены.

Дело в том, что итераторы unordered_set предоставляют только постоянные ссылки на сохраненные элементы. Сначала я думал об использовании const_cast для отбрасывания константы, но при дальнейшем чтении кажется, что это приводит к неопределенному поведению. Любое предложение?

EDIT

Возьмите этот простой пример:

#include <string>
#include <unordered_set>

using namespace std;

void merge_sets(unordered_set<string> &s1, unordered_set<string> &&s2)
{
   // Something like this, which (of course) does not work.
   for (auto it = s2.begin(); it != s2.end(); ++it) {
     s1.insert(std::move(*it));
   }
}

int main()
{
   unordered_set<string> s1, s2;
   // Fill first set:
   s1.insert("hello");
   s1.insert("world");
   // Fill second set.
   s2.insert("foo");
   merge_sets(s1,std::move(s2));
   // After this operation, s2 is empty and s1 contains "hello", "world" and "foo".
}

Другими словами, я хотел бы иметь возможность перемещать элементы из s2 вместо их копирования. Должен быть способ «извлечь» элементы из набора таким образом, чтобы элемент копировался / перемещался, а затем удалялся из текущего набора.

Ответы [ 3 ]

6 голосов
/ 31 мая 2011

В текущей спецификации такой функциональности нет.Но вы не одиноки в этом.Вполне возможно, что мы получим эту функциональность в будущем, но только если такие люди, как вы, будут шуметь по поводу необходимости.

LWG выпуск 839 с комментарием, помеченным "[2009-09-19 Говард добавляет:] ", который описывает API для соединения узлов из одного контейнера на основе узлов в другой.Используя ваш код, он будет выглядеть так:

void merge_sets(unordered_set<string> &s1, unordered_set<string> &&s2)
{
   // Something like this, which (of course) does not work.
   for (auto it = s2.begin(); it != s2.end();) {
     s1.insert(s2.remove(it++));
   }
}

Это не будет включать любое выделение или освобождение памяти.Это даже не потребует перемещения или копирования с вашего элемента.Он буквально передает узел от одного unordered_set<string> к другому.

Сообщите представителю Национального органа, что вам нужны эти функции.Скажите comp.std.c ++, что вам нужен этот функционал.Если вы не уверены, что этот API соответствует вашим потребностям, спросите меня, лично или здесь, и я уточню, смогу ли я.

1 голос
/ 31 мая 2011

Почему бы не объединить два набора, используя один из них в качестве цели, а не объединить их в третий отдельный набор? Это, по крайней мере, позволит вам избежать копирования элементов из одного из исходных наборов (предположительно, вы выберете больший).

Или, если элементы большие, вы должны хранить их косвенно, используя умные указатели (например, boost::shared_ptr<>), и в этом случае будет легко скопировать указатели из двух источников на цель и никогда не копировать реальный объект .

0 голосов
/ 31 мая 2011

Вы не можете изменить элемент в наборе (заказанный или нет), потому что это нарушает гарантию уникальности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...