Допустим, я хочу передать некоторый ссылочный аргумент в поток - стандарт допускает это только с помощью std::ref
.
Теперь давайте рассмотрим этот код с неопределенным поведением (см. Комментарии)
void thread_fun(int& x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
x = -2;
}
int main() {
{
int a = 10;
std::thread t(thread_fun, std::ref(a));
std::cout << "in main: " << a << '\n';
t.detach();
}
// here thread t may still running and writing to an object "a" which
// already destroyed is undefined behaviour
return 0;
}
Без использования std :: ref (a) он не компилируется - это какая-то защита от неопределенного поведения во время компиляции?
Если это так, то для меня большой вопрос , почему нам разрешено передавать необработанные указатели в std :: thread?
Например, я могу переписатьтот же код выше для передачи указателя, например, так:
void thread_fun(int* x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
*x = -2;
}
//...
{
int a = 10;
std::thread t(thread_fun, &a);
//...
}
И это также содержит неопределенное поведение, но здесь нет защиты во время компиляции!?
Что особенного в случае передачи ссылок ??