Universal references in a thread function

后端 未结 2 1241
我寻月下人不归
我寻月下人不归 2021-01-28 03:27

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

相关标签:
2条回答
  • 2021-01-28 03:51

    The issue is that which overload of MyThreadFunc is desired is not deducible by the compiler. There are at least two ways to fix it:

    1. Rename one of the function so that it is clearer which one you want.

    2. Use explicit template parameters:

      StartDetachedThread<void (CObject&)>(MyThreadFunc, object);
      StartDetachedThread<void (CObject&&)>(MyThreadFunc, std::move(object2));
      
    0 讨论(0)
  • 2021-01-28 04:02

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

    Regarding your question:

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

    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();
    

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

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

    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) Is there any value in having StartDetachedThread(FunctionType&& func, Args&&... args) - or is the && unnecessary for FunctionType?

    3) Is there any value whatsoever in using Args&& when starting a thread like this, or should I always use 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.

    0 讨论(0)
提交回复
热议问题