Я написал супер простую оболочку потока, которая берет функцию и запускает ее в потоке, а также предоставляет простой механизм, чтобы сигнализировать потоку, когда пора выходить.Функция запуска выглядит следующим образом:
//tw.hpp
class ThreadWrapper
{
public:
// ...snipped ...
template<typename... Args>
bool start(Args&& ... args)
{
ft_ = std::async(std::launch::async, std::forward<Args>(args)... );
return true;
}
};
Когда я использую ее для функции, не являющейся членом, мне нужно передать const ref обертки в функцию, которая выполняется, чтобы предоставить дескриптор, который может использовать функциячтобы знать, когда выйти:
void lone_worker(const ThreadWrapper& tw)
{
while (!tw.is_quit_requested())
{
std::cout << "working hard alone\n";
sleep(1);
}
}
void nonmember_demo()
{
ThreadWrapper tw;
tw.start(&lone_worker, std::cref(tw)); // the cref is need to avoid hundreds of lines of compiler template puke with no useful error messages
sleep(5);
std::cout << "quitting\n";
tw.request_quit();
}
Я был застигнут врасплох, когда я изначально скомпилировал его без использования std::cref
, буквально сотнями строк puke шаблона компилятора (gcc 8.1.0) и без явной причины.Есть ли что-то, что я не сделал правильно с идеальной пересылкой, чтобы потребовать использования cref?Я предполагаю, что это частично вызвано тем, что класс не подлежит копированию (он содержит std :: future), что немного пахнет, так как, по крайней мере, я предполагаю, что в первую очередь не следует делать копию.Полный пример здесь: https://coliru.stacked -crooked.com / a / 0eb4d6160b44764a