Запустите std :: thread в функции-члене объекта, у которого нет конструктора копирования - PullRequest
0 голосов
/ 24 августа 2018

Я хочу начать std::thread с функции-члена объекта, у которого нет конструктора копирования. Стандартный способ запуска потока в функции-члене (см., Например, Запуск потока с функцией-членом ) требует конструктора копирования. Я думал, что смогу обойти это, используя std::ref (см., Например, std :: thread, передаваемый ссылочными вызовами конструктора копирования ), но не повезло.

Вот мой код. Тема t1 работает, но не t2. Если я попытаюсь раскомментировать две строки, это даст:

error: attempt to use a deleted function 
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:357:5: note: 
in instantiation of function template specialization
'std::__1::__thread_execute<void (Dummy::*)(), std::__1::reference_wrapper<Dummy> , 1>' 
requested here __thread_execute(*__p, _Index()); ^ 
etc.

Как запустить поток непосредственно с print(), без необходимости uselessFunction?

Кроме того, я хотел бы лучше понять ошибку. На какую «удаленную функцию» жалуется компилятор?

#include <iostream>
#include <thread>
using std::cout;
using std::endl;

class Dummy {
public:
    std::atomic<bool> flag;  // atomic kills implicitly created copy constructor
    void print() { std::cout << "hello!" << std::endl; }
};

void uselessFunction(Dummy &d) {
    d.print();
}

int main() {
    Dummy d{};
    std::thread t1(uselessFunction, std::ref(d));  // this works
    // std::thread t2(&Dummy::print, std::ref(d)); // does not work
    t1.join();
    // t2.join();
}

1 Ответ

0 голосов
/ 24 августа 2018

std::thread используйте std::invoke для вызова функции.std::invoke достаточно умен, чтобы иметь возможность взять указатель на объект и вызвать с ним функцию-член.Это означает, что вы можете изменить t2 на

std::thread t2(&Dummy::print, &d);

и получить правильное поведение.

...