Почему этот, казалось бы, безобидный код range-v3 дает сбой?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему этот, казалось бы, безобидный код range-v3 дает сбой?

Сообщение Anonymous »

Я использую Range-v3 примерно так:

Код: Выделить всё

std::vector vec = co_await scanFoo();
auto toProcess = vec
| views::filter([&](auto&& e){ return myPredicate(e); })
| views::transform([](auto&& e) { return std::move(e); })
| ranges::to_vector
Одна и та же логика, написанная итеративно, не воспроизводит сбой:

Код: Выделить всё

for (auto&& e : vec) {
if (myPredicate(e)) {
toProcess.push_back(std::move(e));
}
}
Некоторые подробности об аварии:
  • Переполнение кучи ASAN
  • Это происходит в конструкторе перемещения Foo, выполняемом в пределах диапазонов::to_vector
  • Этот сбой не легко воспроизводится; для воспроизведения требуется непрерывная работа с векторами размеров 0–10000+, иногда до часа.
  • Предположительно, один и тот же элемент перемещается дважды. Я не понимаю, как это возможно, но, похоже, это единственное объяснение здесь.
  • Возможно ли это связано с тем, почему диапазоны C++ "transform -> filter" дважды вызывают преобразование для значений, соответствующих предикат фильтра?
Дополнительные вопросы:
  • Теперь я понимаю, что это не правильный способ перемещения элементов и вместо этого использовать диапазоны::views::move. Однако безопасно ли здесь? Какие еще пистолеты скрываются за ходом? Каковы лучшие практики в этом отношении?


Подробнее здесь: https://stackoverflow.com/questions/787 ... code-crash
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»