Как конструктор 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 во время компиляции.

Другие вопросы по тегам