Обмен индексами двух элементов в std::vector

#c #c 11 #stl

#c #c 11 #stl

Вопрос:

Предполагая вектор объектов, можно ли поменять местами индексы двух элементов? Замена двух элементов на позиции i и j проста:

 tmp=vec[i];
vec[i]=vec[j];
vec[j]=tmp;
 

Однако в приведенном выше примере используется оператор присваивания = и зависит от объектов, хранящихся в vec нем, и способа определения оператора присваивания. Кроме того, это включает в себя создание нового объекта tmp , поэтому я предполагаю, что указатели, направленные на векторные элементы, могут быть признаны недействительными. Мой вопрос в том, возможно ли сохранить объекты, хранящиеся в i и j , и только поменять местами их индексы, чтобы после операции vec[i] указывалось на объект, первоначально найденный в vec[j] , и наоборот?

Комментарии:

1. Если у вас нет векторов указателей (или ссылок), вы не можете заставить индекс массива «ссылаться» на другой объект.

2. Кроме того, всякий раз, когда вам нужно что-то поменять, используйте std::swap . Если этого недостаточно (что должно быть в подавляющем большинстве случаев использования), тогда вы должны рассказать нам, какую проблему вы действительно пытаетесь решить, и какие у вас есть требования, и почему или как std::swap это не соответствует требованиям.

3. сами объекты содержат внутренние ссылки, которые, по-видимому, не так просто сохранить при копировании. По этой причине я бы предпочел не трогать существующие объекты. Обмен необходим, потому что я выполняю параллельное моделирование темперирования / обмена репликами. Я думаю, я мог бы настроить второй вектор с указателями на элементы vec[] и выполнить там замену.

4. @Botond » сами объекты содержат внутренние ссылки, которые, по-видимому, непросто сохранить при копировании » — вот почему семантика перемещения (с помощью конструкторов перемещения, операторов присваивания перемещения и ссылок на значения rvalue) была изобретена в C 11. Тогда ваш ручной обмен не будет tmp = std::move(vec[i]); vec[i] = std::move(vec[j]); vec[j] = std::move(tmp); вообще копироваться, если объекты являются подвижными. Хотя std::swap() вместо этого следует использовать: std::swap(vec[i], vec[j]);