Я кодировал цикл for на C++11, где мне нужно было поместить асинхронный объект обратно в вектор. Я хотел разделить инициализацию объекта на два этапа:
std::vector<std::future<bool>> asyncThreads;
for (int i = 0; i < processorCount; i++) {
auto boundFunc = std::bind(&Foo::foo, this);
auto asyncThread = std::async(std::launch::async, boundFunc)
asyncThreads.push_back(asyncThread);
}
Теперь я понимаю, что объекты boundFunc
и asyncThread
выходят за пределы области видимости в конце цикла for (хотя функция push_back
должна копировать/перемещать значения), но тогда почему работает прямое объявление объектов в push_back call
? Вот так:
std::vector<std::future<bool>> asyncThreads;
for (int i = 0; i < processorCount; i++) {
asyncThreads.push_back(std::async(std::launch::async, std::bind(&Foo::foo, this)));
}
В чем разница между rvalue и lvalue? И как бы я использовал здесь функцию перемещения? Извините, новичок в С++.
Вы можете взглянуть на Что такое семантика перемещения?.
@ user2793618 lvalue — это просто почти все, что имеет имя (int a = 5
), rvalue — это значение или выражение, которое может встречаться только справа от =
(литеральные строки, числа и т. д.)
@FrançoisAndrieux Спасибо за ссылку, было информативно. Но почему копирование объекта future
приводит к сбою кода, а перемещение — нормально?
@user2793618 user2793618 A std::future
нельзя копировать, но можно перемещать. Будущее представляет собой ресурс, которым нельзя осмысленно поделиться, поэтому его семантика копирования явно предотвращается, чтобы избежать ошибок. Вы можете увидеть здесь конструкторы. Конструктор копирования (3) = delete
(отключен), а конструктор перемещения (2) предоставляется.
А, вижу, спасибо!
Объект std::future
нельзя копировать, но можно перемещать. Таким образом, вы должны вызвать перемещение объекта, чтобы поместить его в вектор.
Разница в том, что
std::async(...)
— это выражение rvalue, аasyncThread
— выражение lvalue. Первый пример пытается скопироватьfuture
, а второй перемещает его. Попробуйте использоватьstd::move
.