问题
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
回答1:
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"));
回答2:
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.
回答3:
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