Взгляните на код, приведённый ниже.
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 функции, которая ожидает не константную ссылку.
Здравствуйте, centos, Вы писали:
C>Но, заключив data в std::ref в строке
C>C>std::thread t(update_data_for_widget,w,data);
C>
, код скомпилируется. Почему? Ведь всё ещё передаётся r-value функции, которая ожидает не константную ссылку.
Нет, это не так.
std::ref это метод который просто оборачивает ссылку во враппер-класс std::reference_wrapper<T>, который внутри хранит указатель на T. Сам класс обертка передается уже по значению. У него есть метод преобразования обратно в ссылку operator& T() const. При передачи врапера в метод update_data_for_widget() срабатывает std::reference_wrapper<widget_data>::operator& widget_data(). const.