std :: thread构造函数如何检测rvalue引用?

时间:2016-05-15 19:08:45

标签: c++ multithreading c++11 constructor perfect-forwarding

显然可以将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

3 个答案:

答案 0 :(得分:4)

std::thread构造函数知道其参数的值类别,因为它知道FunctionArgs...是什么,它用来将其参数完美地转发到decay_copy (或同等的)。

实际的线程函数不知道值类别。它总是被调用为rvalue,包含所有rvalue参数 - 这是有道理的:fargs...的副本是线程的本地副本,不会在其他任何地方使用。

答案 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的信息。