如何在类成员上启动新的jthread



我认为这个问题很明显。到目前为止我已经尝试过:

#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;
}

有了新的jthread&使用stop_token?Ps.:当然,可以通过使成员函数为静态或删除stop_token来解决此问题。但我很好奇是否有一个真正的&干净的解决方案,而不是额外的N行黑客攻击。

您可以使用std::bind_frontthis绑定到&test::member并将其传递给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();
}

除了现有的答案之外,有问题的代码不起作用的原因是jthread会尝试将stop_token作为第一个参数传递


std::jthread jt(&test::member, this);

会做

// 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)

这不起作用,因为&test::member需要作为调用

std::invoke(&test::member, this, token)

结果

#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
}

最新更新