вот моя проблема:
У меня есть класс с членом-контейнером, скажем std::vector
. У меня есть функция, скажем, parallelStuff
, которая принимает ссылки на итераторы этого контейнера и выполняет с ним все. Я хочу выполнить указанную функцию параллельно, используя std::thread
Я реализовал это, и он отлично работает. Теперь я хотел написать очень похожую установку с одним небольшим отличием: в рабочей версии, в функции, которая вызывает потоки на parallelStuff
, я получаю итераторы из ссылки на контейнер.
Если, однако, я получаю итераторы из нереференсного контейнера, компиляция завершится неудачей.
Это минимальный рабочий пример для репликации проблемы:
#include <thread>
#include <vector>
class Foo {
public:
Foo() {}
auto const & member() { return member_; }
void parallelStuff(std::vector<int>::const_iterator & it,
std::vector<int>::const_iterator const & end) {
// do stuff while it != end
}
private:
std::vector<int> member_;
};
int main(int argc, char * argv[]) {
auto foo = Foo();
auto& member = foo.member();
// auto member = foo.member(); <-- copy instead of reference, this fails!
auto it = member.begin();
auto end = member.end();
auto t = std::thread(&Foo::parallelStuff, &foo,
std::ref(it), std::ref(end));
t.join();
return 0;
}
Как уже говорилось, если я использую копию member
вместо ссылки, я получаю ошибку
/usr/include/c++/8/thread:120:17: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
Поиск в сообщении об ошибке привел меня только к сайту , объясняющему, что мне нужно обернуть эталонные параметры в std::ref()
, что я уже делаю.
Кто-нибудь понимает, что здесь не так, и, пожалуйста, объясните это (и как это исправить)?
Большое спасибо!
PS: я использую gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04)
с -std=c++17