Obviously it is possible to pass an rvalue reference to std::thread
constructor. My problem is with definition of this constructor in cppreference. It says that this constructor:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
Creates new std::thread object and associates it with a thread of execution. First the constructor copies/moves all arguments (both the function object f and all args...) to thread-accessible storage as if by the function:
template <class T>
typename decay<T>::type decay_copy(T&& v) {
return std::forward<T>(v);
}
As far as I can check:
std::is_same<int, std::decay<int&&>::type>::value
returns true. This means std::decay<T>::type
will drop rvalue reference part of argument. Then how std::thread
constructor knows that which argument is passed by lvalue or rvalue references? Because all T&
and T&&
will be converted to T
by std::decay<T>::type
auto s = std::decay_copy(std::string("hello"));
Is equivalent to:
template<>
std::string std::decay_copy<std::string>(std::string&& src) {
return std::string(std::move(src));
}
std::string s = decay_copy<std::string>(std::string("hello"));
The std::thread
constructor knows the value category of its arguments, because it knows what Function
and Args...
are, which it uses to perfectly forward the its parameters to decay_copy
(or equivalent).
The actual thread function doesn't know the value category. It's always invoked as an rvalue, with all rvalue arguments - which makes sense: the copies of f
and args...
are local to the thread, and won't be used anywhere else.
It is common problem of the perfect forwarding. If you want to restore information about rvalue in the function, you have to use std::forward std::forward . If you are interested in the value type detection you may read this value_category . From the description you can find the information how the compiler recognizes rvalue, xvalue, lvalue, prvalue, gvalue on compile time.
来源:https://stackoverflow.com/questions/37242552/how-stdthread-constructor-detects-rvalue-reference