26

我希望能够定义一个具有一些数据成员的类,以及一个可以访问这些数据成员的函数,这些数据成员是私有的。

然后我想要一个公共函数,它创建一些线程,这些线程对类的数据成员进行操作。我在编译我的代码时遇到了一些麻烦。

不用担心互斥锁或数据保护,这不会成为问题,因为这只是一些用于测试的示例代码。

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() 的匹配调用'

<unresolved overloaded function type>显然,参数 1 从到'没有已知的转换void (foo::*&&)'

嗯,是的,除了编译器无法理解如何解析 foo_func 之外,我不知道这意味着什么——我想。

我如何帮助编译器理解我正在尝试做的事情,这样它就不会再因为任何错误而困扰我了。毫无疑问,我编写的代码是不合法的,如果是这样的话,有人可以向我解释为什么会这样。谢谢!

4

1 回答 1

35

foo_func是一个(非static)成员函数,它需要一个foo对其进行操作的实例。此实例必须提供给线程构造函数。如果您参考std::thread::thread参考页面,它会解释在新线程中执行的代码。相关点是指f指向成员函数的指针:

  • 如果f是指向类的成员函数的指针T,则调用它。返回值被忽略。实际上,执行了以下代码:
    • (t1.*f)(t2, ..., tN)如果 的 类型t1T,则引用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();
}
于 2013-07-04T14:33:24.663 回答