将具有可变参数模板参数的成员函数传递给可变参数构造函数
Passing member functions with variadic template arguments to variadic constructors
我不知道如何将带有可变参数模板参数的成员函数传递给std::thread
构造函数。我有一个接收函数及其参数的方法,需要将它们传递给在新线程中调用并在那里调用传递函数的其他方法。这是简化版本:
class Test
{
public:
template<typename Function, typename... Args>
void Run(Function&& f, Args&&... args)
{
std::thread t(&Test::Operation, this, f, args...); // how???
t.detach();
}
template<typename Function, typename... Args>
void Operation(Function&& f, Args&&... args)
{
f(args...);
}
};
Test test;
test.Run([](const std::string& msg) { std::cout << msg; }, "Hi!");
以这种方式传递参数有问题,我收到以下错误:"std::thread::thread":没有重载函数需要 4 个参数。我该怎么做?
这里的问题是,当您将&Test::Operation
传递给线程构造函数时,它无法推断出&Test::Operation
的模板参数。(如果你想了解为什么不能进行这种推论,你可能应该问一个单独的问题。关键是您需要显式指定 &Test::Operation
的模板参数。
这将看起来像这样:
template<typename Function, typename... Args>
void Run(Function&& f, Args&&... args)
{
std::thread t(&Test::Operation<std::decay_t<Function>, std::decay_t<Args>...>,
this, std::forward<Function>(f), std::forward<Args>(args)...);
t.detach();
}
我为您添加了完美的转发:这很重要,因为您不想执行不必要的复制,对吧?
但是为什么我们需要decay_t
?这是因为线程构造函数在将参数的副本存储在新线程的内部存储中之前会衰减其参数,因此,例如,如果您传入"Hi!"
,则推导的类型是 const char (&)[4]
,但一旦衰减就会变成const char*
,并且衰减是不可逆的,所以Test::Operation
一定不要期待const char (&)[4]
, 无法从衰减的const char*
初始化.因此,必须指定Test::Operation
才能采用衰减类型。
您可能还希望在实际调用期间进行完美转发。
链接: http://coliru.stacked-crooked.com/a/c9d04c03a3758b51
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)