gpt4 book ai didi

c++ - 返回可中断线程的函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:56 25 4
gpt4 key购买 nike

我问了一个previous question关于创建一个函数,该函数指定一个线程运行的函数及其参数,我想传递一个重载函数的名称作为我的线程应该运行的函数,并让线程根据类型选择合适的函数我通过的论点。例如:

void MyThreadFunc(CObject& obj) {}  // Should be called when passing an lvalue
void MyThreadFunc(CObject&& obj) {} // Should be called when passing an rvalue

答案是我应该在调用我的线程创建函数时指定我的线程应该作为模板参数运行的函数的类型:

template<typename FunctionType, typename ...Args>
void StartDetachedThread(FunctionType func, Args&&... args)
{
thread([&]()
{
func(forward<Args>(args)...);
}).detach();
}

CObject object;
StartDetachedThread<void (CObject&)>(MyThreadFunc, std::ref(object)); // Calls MyThreadFunc(CObject&)

CObject object2;
StartDetachedThread<void (CObject&&)>(MyThreadFunc, std::move(object2)); // Calls MyThreadFunc(CObject&&)

这个我明白了。然后,我将这些知识应用到一个可中断的线程实现中,该线程实现是我根据在该站点上找到的片段构建的,但遇到了障碍。这是我精简的线程类:

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

using namespace std;

class interruptible_thread
{
std::thread m_threadInternal;
public:

template<typename FunctionType, typename... Args>
interruptible_thread(FunctionType&& f, Args&&... args)
{
m_threadInternal = std::thread([&]
(typename std::decay<FunctionType>::type&& f
, typename std::decay<Args>::type&&... args)
{
f(std::forward<Args>(args)...); /// ***** COMPILER ERROR HERE
}
, std::forward<FunctionType>(f)
, std::forward<Args>(args)...);
}
~interruptible_thread() {}
interruptible_thread(interruptible_thread&& rhs) { m_threadInternal = std::move(rhs.m_threadInternal); }
};

class CObject {};
void MyThreadFunc(CObject& obj) {}
void MyThreadFunc(CObject&& obj) {}

template<typename FunctionType, typename... Args>
interruptible_thread CreateThread(FunctionType&& f, Args&&... args)
{
return interruptible_thread(f, args...);
}

我知道在构造我的 interruptible_thread 时我不能指定模板参数,所以编写了 CreateThread() 来为我做这件事。但是,当我编码时

CObject o2;
interruptible_thread thr = CreateThread<void (CObject&&)>(MyThreadFunc, std::move(o2));

VS 2017 提示上述行:

'void (CObject &&)': cannot convert argument 1 from 'CObject' to 'CObject &&'
You cannot bind an lvalue to an rvalue reference

现在,我可能已经看这个太久了,但我不明白这个问题。有人可以温和地解释一下吗?

最佳答案

您忘记在 CreateThread() 中完美转发 args:

template<typename FunctionType, typename... Args>
interruptible_thread CreateThread(FunctionType&& f, Args&&... args)
{
return interruptible_thread(std::forward<FunctionType>(f), std::forward<Args>(args)...);
}

如果您不这样做,那么 args 将从右值引用变为左值引用,以便传递给 interruptible_thread,这将不起作用。

另请注意:避免在 Visual Studio 中使用名称 CreateThread,已有一个名为 CreateThread 的 WinAPI,这可能会导致冲突。

关于c++ - 返回可中断线程的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48371562/

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