Почему у меня есть 2 копии объекта вместо 1?
Когда вы раскручиваете поток, параметры копируются в объект потока.Эти параметры затем копируются в реальный поток, который создается, поэтому у вас есть две копии.Вот почему вы должны использовать std::ref
, когда хотите передать параметр, который функция принимает по ссылке.
Какова точная причина, по которой конструктор потока может принять объект, адрес илиstd :: ref?Использует ли эта версия конструктора (который, я признаю, я не до конца понимаю)
std::thread
в основном запускает новый поток с помощью вызова, подобного
std::invoke(decay_copy(std::forward<Function>(f)),
decay_copy(std::forward<Args>(args))...);
std::invoke
создан для обработки всех видов вызываемых типов, и один из них, когда он имеет указатель на функцию-член и объект, и вызывает функцию соответствующим образом.Он также знает о std::reference_wrapper
и может обрабатывать вызов указателя на функцию-член на std::reference_wrapper
объекте.
Если мы исключаем первый случай (так как он неэффективен), что я должениспользуйте между &conan
и std::ref(conan)
?
Это в основном основано на мнении.По сути, они оба делают одно и то же, хотя первую версию писать короче.
Это как-то связано с синтаксисом, необходимым для std::bind
?
Вид,std::bind
operator()
также реализован с использованием std::invoke
, поэтому у них очень общий интерфейс.
Все это говорит о том, что вы можете использовать лямбда-выражения для создания общего интерфейса.
thread t(&Warrior::attack, conan, 5);
можно переписать как
thread t([&](){ return conan.attack(5); });
И вы можете использовать эту форму практически для любой другой функции, которую вы хотите вызвать.Я считаю, что анализировать лямбду легче.