gpt4 book ai didi

c++ - 子类化 std::thread:构造函数中可变参数模板函数的问题

转载 作者:行者123 更新时间:2023-11-28 01:48:13 25 4
gpt4 key购买 nike

我正在尝试对 std::thread 进行子类化,以便在调用者传入函数之前在新线程上执行子类的成员函数。类似于以下无效代码:

#include <thread>
#include <utility>

class MyThread : public std::thread {
template<class Func, class... Args>
void start(Func&& func, Args&&... args) {
... // Useful, thread-specific action
func(args...);
}
public:
template<class Func, class... Args>
MyThread(Func&& func, Args&&... args)
: std::thread{[=]{start(std::forward<Func>(func),
std::forward<Args>(args)...);}} {
}
};

g++ -std=c++11 上述代码存在以下问题:

MyThread.h: In lambda function:
MyThread.h:ii:jj: error: parameter packs not expanded with '...':
std::forward<Args>(args)...);}}
^

我在初始化列表中尝试了十几种不同的变体,但都无济于事。

我怎样才能做我想做的事?

最佳答案

我之前做这个的时候最大的困难是获取std::thread的所有行为。它的构造函数不仅可以接受一个指向自由函数的指针,还可以接受一个类方法指针,然后是该类的一个对象作为第一个参数。有许多变体:类方法、类函数对象数据成员、类类型的对象与指向对象的指针等。

这是针对 C++14 的:

class MyThread : public std::thread {
void prolog() const { std::cout << "prolog\n"; }

public:
template <typename... ArgTypes>
MyThread(ArgTypes&&... args) :
std::thread(
[this, bfunc = std::bind(std::forward<ArgTypes>(args)...)]
() mutable {
prolog();
bfunc();
})
{ }
};

如果将 prolog 代码放在 lambda 中并且它不调用类方法,则不需要捕获 this

对于 C++11,由于缺少捕获初始值设定项,需要进行一个小改动,因此绑定(bind)必须作为参数传递给 std::thread:

std::thread(
[this]
(decltype(std::bind(std::forward<ArgTypes>(args)...))&& bfunc) mutable {
prolog();
bfunc();
}, std::bind(std::forward<ArgTypes>(args)...))

下面是一个同样练习std::thread类成员形式的测试程序:

int main()
{
auto x = MyThread([](){ std::cout << "lambda\n"; });
x.join();

struct mystruct {
void func() { std::cout << "mystruct::func\n"; }
} obj;
auto y = MyThread(&mystruct::func, &obj);
y.join();

return 0;
}

我还没有检查过,但我有点担心 this 的捕获,在其他解决方案中也看到,在某些情况下并不安全。考虑对象何时是移动的右值,如 std::thread t = MyThread(args)。我认为 MyThread 对象会在它创建的线程使用完它之前消失。 “线程”将被移动到一个新对象中并仍在运行,但捕获的 this 指针将指向一个现在过时的对象。

我认为您需要确保您的构造函数不会返回,直到您的新线程使用完所有对类或类成员的引用或指针。如果可能,按值(value)捕获会有所帮助。或者 prolog() 可能是一个静态类方法。

关于c++ - 子类化 std::thread:构造函数中可变参数模板函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44011601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com