GCC 4.9’s unordered_set и std :: move

При перемещении unordered_set на GCC 4.9, а затем повторно используя перемещенный объект, я получаю деление на ноль, когда добавляю к нему.

Мое понимание (от http://en.cppreference.com/w/cpp/utility/move) заключается в том, что перемещенный объект может использоваться при условии, что ни одно из его предварительных условий не нарушено. призвание clear() с перемещенным набором все в порядке (что имеет смысл в контексте предварительных условий), но мне не ясно, что я нарушаю любое предварительное условие, добавляя новый элемент.

Пример кода:

#include <unordered_set>
using namespace std;
void foo(unordered_set<int> &&a) {
unordered_set<int> copy = std::move(a);
}

void test() {
unordered_set<int> a;
for (int i = 0; i < 12; ++i) a.insert(i);
foo(std::move(a));

a.clear();
a.insert(34); // divide by zero here
}

int main() {
test();
}​

Этот код прекрасно работает на GCC4.7 — это проблема в GCC4.9? unordered_set реализация или, как я понимаю, что значит нарушать предварительные условия для перемещенных объектов?

5

Решение

Это PR 61143. Это было исправлено для gcc-4.10, и исправление было перенесено вовремя для 4.9.1.

9

Другие решения

Марк Глисс уже направил вас к ошибке GCC, но чтобы ответить на ваш вопрос:

это проблема … в моем понимании того, что значит нарушать предварительные условия для перемещенных объектов?

Нет, это не так, ваше понимание верно. Работа с кодом в вашем вопросе — это не просто расширение GCC, ваша программа отлично работает. Предполагается, что перемещенный объект типа, определенного в стандартной библиотеке, останется пригодным для использования. Вы ничего не знаете о его состоянии, но, например, любой контейнер является пустым или не пустым, поэтому перемещенный контейнер также является пустым или не пустым. Что из этого не определено, но ваша программа может проверить, и реализация стандартной библиотеки должна вести себя так, как нужно для результата проверки вашей программы.

3

По вопросам рекламы [email protected]