Q:

Universal references in a thread function

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.
Hhowever, VS 2017 complains: 
'StartDetachedThread': no matching overloaded function found
'void StartDetachedThread(FunctionType,Args &&...)': could not deduce template argument for 'FunctionType'

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

A:

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. 

