Меня интересуют (и путают) детали построения объекта std::thread
. Согласно cppreference, как функция потока, так и все аргументы копируются в некоторую доступную потоку хранилище, а затем вызывают.Детали в процессе создания объекта std :: thread
1) Что именно такое доступное для хранения данных хранилище? Является ли он семантически эквивалентен некоторому потоковому локальному хранилищу, а переменные разрушаются после возврата функции потока?
2) Что такое категория значений аргументов при передаче функции потока? Описание на cppreference указывает, что они передаются как l-значения (в любом случае им даются имена). Мои тесты на GCC и clang кажутся противоположными, т. Е. R-значениями. В частности, следующий код не компилируется:
void f(int& a) {
std::cout << ++a << '\n';
}
int main() {
std::thread t(&f, 1);
t.join();
return 0;
}
Он компилирует, если мы изменим f
к
void f(int&& a) {
std::cout << ++a << '\n';
}
int main() {
std::thread t(&f, 1);
t.join();
return 0;
}
Итак, что же стандарт сказать об этом?
Итак, новый поток выполняет 'Invoke (DECAY_COPY (Std :: вперед (е)), DECAY_COPY (станд :: вперед (арг)) ...)' 'за исключением того, DECAY_COPY' уже сделано в конструирующем потоке. Я бы сделал вывод о том, что временные файлы, возвращаемые 'DECAY_COPY', разрушаются после возврата« INVOKE », а разрушение выполняется построенным потоком. –
Lingxi
Формулировка о хранении, по-видимому, была вдохновлена документами boost.thread («func копируется в хранилище, управляемое внутри библиотеки потоков ...») – Cubbi