How does the std :: thread constructor detect an rvalue link?

Obviously, you can pass the rvalue reference to the std::thread constructor. My problem is defining this constructor in cppreference . He says this constructor:

 template< class Function, class... Args > explicit thread( Function&& f, Args&&... args ); 

Creates a new std :: thread object and associates it with thread execution. First, the constructor copies / moves all the arguments (both the object of the function f and all the arguments ...) to the storage accessible by the stream, as if by 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 that std::decay<T>::type will discard the reference part of the rvalue value of the argument. Then how does the std::thread constructor know which argument is passed by lvalue or rvalue references? Since all T& and T&& will be converted to T on std::decay<T>::type

+2
source share
3 answers
 auto s = std::decay_copy(std::string("hello")); 

It 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
source

The constructor std::thread knows the category of the values โ€‹โ€‹of its arguments, because it knows that Function and Args... which it uses to ideally redirect its parameters to decay_copy (or the equivalent).

The actual stream function does not know the category of values. It is always called as an rvalue with all rvalue arguments - which makes sense: copies of f and Args... are local to the stream and will not be used anywhere else.

+3
source

This is a common perfect shipment problem. If you want to retrieve rvalue information in a function, you must use std :: forward std :: forward . If you are interested in detecting the type of a value, you can read this value_category . From the description you can find information about how the compiler recognizes rvalue, xvalue, lvalue, prvalue, gvalue at compile time.

+1
source

Source: https://habr.com/ru/post/1443775/


All Articles