0

I want to create a thread that will automatically join after the work is done. So, I wrote the fallowing code:

#include <iostream>
#include <thread>
#include <chrono>
#include <future>

using namespace std;

class Foo
{
public:
    void work(atomic_bool & isWorking);

};

void Foo::work(atomic_bool & isWorking)
{
    //dosomestuff;
    int myVar = 0;
    while (myVar != 5)
    {
        myVar++;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    isWorking = true;
    return;
}

int main()
{
    std::atomic<bool> imdone;
    imdone = false;
    std::thread t1(&Foo::work, Foo(), imdone);

    while (true)
    {
        std::cout << "Is Joinable: " << t1.joinable() << "\n";
        if (imdone)
        {
            imdone = false;
            t1.join();
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    cin.get();
}

I thought that I can pass argument like this: std::thread t1(&Foo::work, Foo(), imdone);, but not in case when the argument is a pointer. How am I supose to pass a pointer in this situation?

Salin
  • 47
  • 1
  • 10

1 Answers1

2

You create an object of the type whose member you want to call and pass its address like this:

Foo foo; // create an object
std::thread t1(&Foo::work, &foo, ...); // pass its address

In addition you are passing a reference so you need to use std::ref like this:

Foo foo; // create an object
std::thread t1(&Foo::work, &foo, std::ref(imdone)); // use std::ref()
Galik
  • 47,303
  • 4
  • 80
  • 117
  • It worked when I used `std::ref()`, but I dont understand why I have to use this function to make it work. What do I use it for, and when do I use it? – Salin Apr 23 '18 at 17:59
  • @Salin https://stackoverflow.com/questions/34078208/passing-object-by-reference-to-stdthread-in-c11/34078246 Basically to make sure that you really mean to capture by reference and that you understand that the reference must live longer than the thread. – Quimby Apr 23 '18 at 18:06
  • @Salin You use it when the function you are calling expects a *reference*. It is needed because, when making a thread object, **all** parameters are **copied**. So you need to "hide" references within another object. – Galik Apr 23 '18 at 18:37