Взгляните на код, приведённый ниже.
void update_data_for_widget(widget_id w, widget_data& data);
void oops_again(widget_id w)
{
widget_data data;
std::thread t(update_data_for_widget,w,data);
display_status();
t.join();
process_widget_data(data);
}
Конструктор std::thread копирует предоставленные значения во внутреннее хранилище.
Внутренний код передаёт скопированные аргументы в качестве r-значений функции update_data_for_widget.
Код не будет скомпилирован, потому что нельзя передать r-value функции, которая ожидает не константную ссылку.
Но, заключив data в std::ref в строке
std::thread t(update_data_for_widget,w,data);
, код скомпилируется. Почему? Ведь всё ещё передаётся r-value функции, которая ожидает не константную ссылку.