std::thread 构造函数如何检测右值引用?
how std::thread constructor detects rvalue reference?
显然可以将右值引用传递给 std::thread
构造函数。我的问题是 cppreference 中此构造函数的定义。它说这个构造函数:
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);
}
据我所知:
std::is_same<int, std::decay<int&&>::type>::value
returns 是的。这意味着 std::decay<T>::type
将删除参数的右值引用部分。那么 std::thread
构造函数如何知道左值或右值引用传递了哪个参数?因为所有T&
和T&&
都会被std::decay<T>::type
转换成T
auto s = std::decay_copy(std::string("hello"));
相当于:
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"));
完美转发通病。如果要恢复函数中右值的信息,则必须使用 std::forward std::forward . If you are interested in the value type detection you may read this value_category 。从描述中您可以找到编译器如何在编译时识别右值、x值、左值、prvalue、gvalue的信息。
std::thread
构造函数知道其参数的值类别,因为它知道 Function
和 Args...
是什么,它使用它们将其参数完美地转发给 decay_copy
(或同等学历)。
实际线程函数不知道值类别。它总是作为右值调用,所有右值参数 - 这是有道理的:f
和 args...
的副本是线程本地的,不会在其他任何地方使用。
显然可以将右值引用传递给 std::thread
构造函数。我的问题是 cppreference 中此构造函数的定义。它说这个构造函数:
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);
}
据我所知:
std::is_same<int, std::decay<int&&>::type>::value
returns 是的。这意味着 std::decay<T>::type
将删除参数的右值引用部分。那么 std::thread
构造函数如何知道左值或右值引用传递了哪个参数?因为所有T&
和T&&
都会被std::decay<T>::type
T
auto s = std::decay_copy(std::string("hello"));
相当于:
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"));
完美转发通病。如果要恢复函数中右值的信息,则必须使用 std::forward std::forward . If you are interested in the value type detection you may read this value_category 。从描述中您可以找到编译器如何在编译时识别右值、x值、左值、prvalue、gvalue的信息。
std::thread
构造函数知道其参数的值类别,因为它知道 Function
和 Args...
是什么,它使用它们将其参数完美地转发给 decay_copy
(或同等学历)。
实际线程函数不知道值类别。它总是作为右值调用,所有右值参数 - 这是有道理的:f
和 args...
的副本是线程本地的,不会在其他任何地方使用。