线程函数中的通用引用 [英] Universal references in a thread function

查看:49
本文介绍了线程函数中的通用引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习完美的转发和&&的使用.在功能模板中(请参阅我之前的问题),并且想知道我是否使用了以下 StartDetachedThread()中的 Args& 是合理的:

I have been learning about perfect forwarding and the use of && in function templates (see this previous question of mine) and would like to know if my use of Args&& in StartDetachedThread() below is justified:

#include <thread>

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

// ** Will not compile with this function declaration! **
void MyThreadFunc(CObject&&)
{
}

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

int main()
{
    CObject object;
    StartDetachedThread(MyThreadFunc, object);

    CObject object2;
    StartDetachedThread(MyThreadFunc, std::move(object2));
    return 0;
}

此代码仅创建一个分离的线程,运行提供的函数并传递给其提供的参数.

This code simply creates a detached thread, running the supplied function passing to it the supplied arguments.

但是,VS 2017抱怨:

Hhowever, VS 2017 complains:

'StartDetachedThread': no matching overloaded function found
'void StartDetachedThread(FunctionType,Args &&...)': could not deduce template argument for 'FunctionType'

1)我知道传递给 thread 构造函数的参数是先复制的,然后通过引用传递给新线程,所以我尝试使用 MyThreadFunc(CObject&&)在我传递右值引用永远不会起作用时被调用吗?

1) I know that arguments passed to the thread constructor are copied first, then passed by reference to the new thread, so is my attempt to have MyThreadFunc(CObject&&) called when I pass an rvalue reference never going to work?

2)拥有 StartDetachedThread(FunctionType&& func,Args&& ... args)有什么价值-还是&& FunctionType 不需要?

2) Is there any value in having StartDetachedThread(FunctionType&& func, Args&&... args) - or is the && unnecessary for FunctionType?

3)启动这样的线程时,使用 Args& 有什么价值,还是我应该始终使用 Args ?

3) Is there any value whatsoever in using Args&& when starting a thread like this, or should I always use Args?

推荐答案

您的代码中的问题与 std :: thread 无关,这是因为 MyThreadFunc 在这种情况下是模棱两可的:

The problem in your code has nothing to do with std::thread, it is because MyThreadFunc is ambiguous in this context:

// Which MyThreadFunc should be used?
StartDetachedThread(MyThreadFunc, object);

关于您的问题:

1)我知道传递给线程构造函数的参数将首先复制,然后通过引用传递给新线程[...]

1) I know that arguments passed to the thread constructor are copied first, then passed by reference to the new thread, [...]

在您的示例中,唯一的副本是lambda的副本.参数未在此处复制,如果要复制参数,则应使用类似以下内容的方法:

In your example, the only copy is the copy of the lambda. The arguments are not copied here, if you want the argument to be copied you should use something like this:

std::thread(std::move(func), std::forward<Args>(args)...).detach();

...在此将参数转发到 std :: thread 构造函数.

...where you forward the arguments to std::thread constructor.

这更安全.—想一想如果函数 StartDetachedThread 在线程仍在运行时结束,会发生什么情况?

This is safer. — Think about what happens if the function StartDetachedThread ends while the thread is still running?

如果使用此选项,则需要使用 std :: ref :

If you use this, you need to explicitly tell the compiler you want to call the reference version for object1 by using std::ref:

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

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

2)拥有 StartDetachedThread(FunctionType&& func,Args&& ... args)有什么价值-还是&& FunctionType 不需要?

2) Is there any value in having StartDetachedThread(FunctionType&& func, Args&&... args) - or is the && unnecessary for FunctionType?

3)启动这样的线程时,使用 Args& 有什么价值,还是我应该始终使用 Args ?

3) Is there any value whatsoever in using Args&& when starting a thread like this, or should I always use Args?

使用转发引用,您无需移动所有内容即可调用 StartDetachedThread .如果使用上述方法构造 std :: thread ,则无论如何都将为 func args 进行复制.

Using forwarding references allows you to call StartDetachedThread without having to move everything. If you use the above way for constructing a std::thread, then copies will be made for func and args anyway.

这篇关于线程函数中的通用引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆