显然可以将rvalue引用传递给std::thread
构造函数。我的问题是在cppreference中定义了这个构造函数。它说这个构造函数:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
创建新的std :: thread对象并将其与线程关联 执行。首先,构造函数复制/移动所有参数(两者都是 函数对象f和所有args ...)到线程可访问的存储,就好像 通过功能:
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
返回true。这意味着std::decay<T>::type
将删除参数的右值参考部分。那么std::thread
构造函数如何知道lvalue或rvalue引用传递了哪个参数?因为所有T&
和T&&
都会被T
std::decay<T>::type
答案 0 :(得分:4)
std::thread
构造函数知道其参数的值类别,因为它知道Function
和Args...
是什么,它用来将其参数完美地转发到decay_copy
(或同等的)。
实际的线程函数不知道值类别。它总是被调用为rvalue,包含所有rvalue参数 - 这是有道理的:f
和args...
的副本是线程的本地副本,不会在其他任何地方使用。
答案 1 :(得分:2)
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"));
答案 2 :(得分:1)
这是完美转发的常见问题。如果要在函数中恢复有关rvalue的信息,则必须使用std :: forward std::forward。如果您对值类型检测感兴趣,可以阅读此value_category。从描述中,您可以找到编译器在编译时如何识别rvalue,xvalue,lvalue,prvalue,gvalue的信息。