Как конструктор std::thread обнаруживает ссылку на значение?
Очевидно, что можно передать ссылку на значение std::thread
конструктор. Моя проблема с определением этого конструктора в cppreference. Это говорит о том, что этот конструктор:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
Создает новый объект std::thread и связывает его с потоком выполнения. Сначала конструктор копирует / перемещает все аргументы (как объект функции f, так и все аргументы...) в доступное для потока хранилище, как если бы это было сделано с помощью функции:
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
возвращает истину. Это означает std::decay<T>::type
удалит rvalue ссылочную часть аргумента. Тогда как std::thread
конструктор знает, какой аргумент передается по ссылкам lvalue или rvalue? Потому что все T&
а также T&&
будет преобразован в T
от std::decay<T>::type
3 ответа
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::thread
конструктор знает категорию значений своих аргументов, потому что он знает, что Function
а также Args...
есть, который он использует, чтобы идеально переслать свои параметры в decay_copy
(или эквивалент).
Фактическая функция потока не знает категорию значения. Он всегда вызывается как rvalue со всеми аргументами rvalue - что имеет смысл: копии f
а также args...
являются локальными для потока и не будут использоваться где-либо еще.
Это общая проблема идеальной пересылки. Если вы хотите восстановить информацию о rvalue в функции, вы должны использовать std:: forward std:: forward. Если вы заинтересованы в обнаружении типа значения, вы можете прочитать эту value_category. Из описания вы можете найти информацию о том, как компилятор распознает rvalue, xvalue, lvalue, prvalue, gvalue во время компиляции.