как конструктор std:: thread обнаруживает ссылку rvalue?


Очевидно, что можно передать ссылку rvalue в конструктор 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

Возвращает true. Это означает, что std::decay<T>::type отбросит ссылочную часть аргумента rvalue. Тогда как std::thread конструктор знает, какой аргумент передается ссылками lvalue или rvalue? Потому что все T& и T&& будут преобразованы в T через std::decay<T>::type

3 2

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 во время компиляции.