Создайте поток внутри класса с функцией из того же класса

Я хочу иметь возможность определить класс с некоторыми членами данных и функцию, которая имеет доступ к тем членам данных, которые должны быть частными.

Затем я хочу публичную функцию, которая создает некоторые потоки, которые работают с членами данных класса. У меня возникли проблемы с компиляцией моего кода.

Не беспокойтесь о мьютексе или защите данных, это не будет проблемой, так как это всего лишь пример кода для тестирования.

class foo {
    public:
    void make_foo_func_threads();

    private:
    void foo_func();

    char private_data;
    std::vector<std::thread> some_threads;
}

void foo::foo_func() {
    while(1) {
        private_data = 'A';
    }
}

void foo::make_foo_func_thread() {
    for(...) some_threads.push_back(std::thread(foo_func));
    for(...) some_threads.join();
}

Компилятор сообщает мне об ошибке:

'нет соответствующего вызова в std:: thread:: thread()'

По-видимому, нет никакого известного преобразования для аргумента 1 от <unresolved overloaded function type> до void (foo::*&&)'.

Эмм, да, я не знаю, что это значит, кроме компилятора, возникает проблема с пониманием того, как разрешить foo_func - я думаю.

Как я могу помочь компилятору понять, что я пытаюсь сделать, поэтому он не будет беспокоить меня с помощью каких-либо ошибок. Без сомнения, код, который я написал, не является законным, и, если это так, кто-то может объяснить, почему это так. Спасибо!

Ответ 1

foo_func является (не static) функцией-членом, и для этого требуется экземпляр foo. Этот экземпляр должен быть предоставлен конструктору потока. Если вы ссылаетесь на страницу std:: thread:: thread, она объясняет, какой код выполняется в новом потоке. Соответствующим пунктом является то, что относится к f, являющемуся указателем на функцию-член:

  • Если f является указателем на функцию-член класса T, то он вызывается. Возвращаемое значение игнорируется. Эффективно выполняется следующий код:
    • (t1.*f)(t2, ..., tN), если тип t1 либо T, ссылка на T, либо ссылка на тип, полученный из T.
    • ((*t1).*f)(t2, ..., tN) в противном случае.

поэтому ясно, что экземпляр требуется.

Изменить на:

for(...) some_threads.push_back(std::thread(&foo::foo_func, this));

Простой пример:

#include <iostream>
#include <thread>
#include <vector>

class foo
{
public:
    void make_foo_func_threads()
    {
        for (int i = 0; i < 5; ++i)
            some_threads.push_back(std::thread(&foo::foo_func, this));
        for (auto& t: some_threads) t.join();
    }

private:
    void foo_func() { std::cout << "Hello\n"; }
    std::vector<std::thread> some_threads;
};

int main()
{
    foo f;
    f.make_foo_func_threads();
}