Reputation: 700
I think the question is quite obvious. The I have tried so far:
#include <thread>
#include <chrono>
using namespace std::literals::chrono_literals;
class test
{
public:
void member(std::stop_token stoken)
{
std::this_thread::sleep_for(1s);
}
void run()
{
// None compiles correctly
// std::jthread jt(&member);
// std::jthread jt(&test::member, this);
}
};
int main()
{
test t;
t.run();
return 0;
}
Is it possible with the new jthread & with using stop_token? Ps.: Of course it's possible to workaround it by making the member function static or by removing the stop_token. But I'm curious if there's a real & clean solution instead of extra N lines of hacking.
Upvotes: 4
Views: 1687
Reputation: 10604
in addition to existing answer, the reason the code in question doesn't work is because jthread
would try to pass stop_token
as first parameter
std::jthread jt(&test::member, this);
would do
// with stop_token
// note: stop token is passed as first parameter
std::invoke(&test::member, the_inner_token, this)
// or (without stop_token)
std::invoke(&test::member, this)
which doesn't work because &test::member
need to be invoke as
std::invoke(&test::member, this, token)
as a result
#include <thread>
static void before(std::stop_token, int);
static void raw(int);
static void after(int,std::stop_token);
void run(){
std::jthread(before, 0); // work
std::jthread(raw, 0); // work
std::jthread(after, 0); // not work
}
Upvotes: 4
Reputation: 42861
You can use std::bind_front
to bind this
to &test::member
and pass it to jthread
:
#include <thread>
#include <chrono>
#include <functional>
using namespace std::literals::chrono_literals;
class test
{
public:
void member(std::stop_token stoken)
{
std::this_thread::sleep_for(1s);
}
void run()
{
std::jthread jt(std::bind_front(&test::member, this));
}
};
int main()
{
test t;
t.run();
}
Upvotes: 5