Назначение перемещения в контейнерах: состояние ранее содержащихся объектов - PullRequest
0 голосов
/ 08 октября 2018

Исходя из другого вопроса (на самом деле, скорее этот , но первый лучше справочный), я не смог найти соответствующую ссылку в стандарте, кроме 20.5.5.15:

Объекты типов, определенных в стандартной библиотеке C ++, могут быть перемещены из (15.8).Операции перемещения могут быть явно указаны или неявно сгенерированы.Если не указано иное, такие перемещенные объекты должны быть помещены в действительное, но неопределенное состояние.

Существуют ли какие-либо требования к элементам, ранее содержавшимся в контейнере назначения, например, уничтоженные до назначения?

Пример:

std::list<SomeClass> v1({10, 12});
std::list<SomeClass> v2({7});
v1 = std::move(v2);
for(auto sc : v2)
{
    std::cout << sc << ' ';
}

Хотя GCC вообще ничего не выводил (std::vector и std::list), он получил бы 10 12 в качестве допустимого выхода (соответствующий operator<< при условии) (например, полученный путем простой замены содержимого, особенно , а не , удаляя ранее содержащиеся объекты)?

На данный момент я бы сказал «да», но не уверенполагаться и слишком любопытно не публиковать вопрос ...

Если это законно, станет ли неожиданным для разработчиков, если элементы не будут уничтожены немедленно (например, вследствие этого некоторые ресурсы остаются открытыми, пока разработчик ожидает, что онизакрыться)?

1 Ответ

0 голосов
/ 08 октября 2018

В [container.requirements.general] мы видим

Все существующие элементы a либо назначены, либо уничтожены. Гарантирует, что : a будет равно значению, которое rv имело до этого назначения.

Где a - пункт назначения, а rv - значение.Это может быть достигнуто путем замены 1 на элементы источника назначения, но, скорее всего, это происходит путем изменения размера, а затем перемещения.

  1. Это должно бытьчерез неспециализованный __swap, чтобы гарантировать, что назначения перемещения действительно имеют место.
...