31

I want to be able to define a class with some data members, and a function which has access to those data members, which are to be private.

I then want a public function, which creates some threads, which operate on the data members of the class. I am having some trouble getting my code to compile.

Don't worry about mutex or data protection, this isn't going to be a problem, since this is just some example code for testing.

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();
}

The compiler is giving me the error:

'no matching call to std::thread::thread()'

Apparently there is 'no known conversion for argument 1 from <unresolved overloaded function type> to void (foo::*&&)'.

Erm, yeah, I have no idea what that means apart from the compiler is having trouble understanding how to resolve foo_func - I think.

How can I help the compiler understand what I am trying to do, so it won't bother me with any more errors. No doubt the code I have written is not legal, and if that is the case could someone explain why that is the case to me. Thanks!

1 Answer 1

41

foo_func is a (non-static) member function, and it needs an instance of foo on which to operate. This instance must be provided to the thread constructor. If you refer to the std::thread::thread reference page it explains what code is executed in the new thread. The relevant point is that which refers to f being a pointer to member function:

  • If f is pointer to a member function of class T, then it is called. The return value is ignored. Effectively, the following code is executed:
    • (t1.*f)(t2, ..., tN) if the type of t1 is either T, reference to T or reference to type derived from T.
    • ((*t1).*f)(t2, ..., tN) otherwise.

so it is clear that the instance is required.

Change to:

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

Simple example:

#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();
}
Sign up to request clarification or add additional context in comments.

4 Comments

Okay, that's great! One problem though, my program drops out of the bottom of main, even though there is supposed to be an infinite loop running. thread.join() doesn't seem to be waiting for the threads to join!
@EdwardBird, could you post the full program to stacked-crooked or similar and post a link? Or better, post another question to get other people's contribution (and this answer, and the other, have addressed the question as posted).
Oops, no my bad I didn't put f.make_foo_func_threads(); in main! Sorry about that, it works fine everybody DONT PANIC! >.<
Thanks this answer save my time, but a simple question appeard in my mind, why we use pointer to class or this in thread? my means =some_threads.push_back(std::thread(&foo::foo_func, this));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.