Конструктор std::thread передается по ссылке при использовании функции-члена класса

Я провел небольшое исследование нового C++11 rvalue и перенес lvalue. Вот пример того, что я нашел и прочитал:

какие-делает-трет-двойной амперсанд-среднего-в-c11

как-stdthread-конструктор-детектирует-Rvalue-справочник

stdthread-и-Rvalue-справочник

Я также проинформировал себя о ссылках

Move_Semantics

rvalue_references

Предложение добавить ссылку Rvalue на язык C++

В частности, относительно std::thread конструктор, я нашел

как к созданию-а-нить-внутри-а-класса-функции

и использовал один из ответов, чтобы написать простой код

#pragma once
#ifndef CONSUMER_H
#define CONSUMER_H

#include "Mailbox.h"
#include <thread>
#include <iostream>

class Consumer
{
private:
    Mailbox mailbox;
    std::thread consumer;
public:
    Consumer(Mailbox& newMailbox);
    ~Consumer();
    void operator()() { std::cout << consumer.get_id() << "starting\n"; }
    void start();
    void run();
};

Consumer::Consumer(Mailbox& newMailbox)
{
    this->mailbox = newMailbox;
}

void Consumer::start()
{
    consumer = std::thread(&Consumer::run, this); <-- need understanding
}

#endif

Проверка конструктора `std::thread

станд:: Тема::Thread

Я наблюдаю шаблон, который использует параметры rvalue. Я понимаю что std::thread можно инициировать на простом примере

void run(void) {std::cout << "I'm running";}

std::thread(run);

который появляется прямо, пока я не в классе, в результате чего мне нужно сделать следующее

consumer = std::thread(&Consumer::run, this); <-- need understanding

потому что я узнал от Джонатана Уэйкли, что run() является нестатической функцией-членом и должна выполняться на объекте. Как новый поток должен знать, какой объект вызывать, если вы этого не говорите?

Это имеет некоторый смысл, но необходимость передавать по ссылке функцию класса не делает, так как я видел A a; A&& ref = A() возможный. Я очень запутался в rvalues ​​и просто хочу понять, почему код, который я написал выше, необходим для передачи функции std::thread,

Я уверен, что я также не понимаю вариационные шаблоны, которые также хорошо понимают std::thread конструктор шаблонов.

1 ответ

Я наблюдаю шаблон, который использует параметры rvalue.

Нет, std::thread Конструктор использует переадресацию ссылок, что означает, что они могут принимать аргументы любого типа и выводить ссылки либо lvalue, либо rvalue, в зависимости от типа аргумента.

Прочитайте ссылки на пересылку и универсальные ссылки в C++ 11 (Скотт Мейерс ввел для них название "универсальная ссылка", но теперь официальным названием является "ссылка на пересылку").

Это имеет некоторый смысл, но необходимость передавать по ссылке функцию класса не

Ты в замешательстве, &Consumer::run не является ссылкой любого рода. Символ & как часть typename означает ссылку, но когда она появляется слева от выражения, это оператор "address of", который формирует указатель. В этом случае он формирует указатель на функцию-член.

Выражение std::thread(&Consumer::run, this) создает поток с двумя аргументами, указателем на функцию-член, которая должна выполняться в новом потоке, и указателем на объект, для которого будет вызываться функция-член. Итак, в новой ветке происходит нечто подобное:

auto pointer_to_member_function = &Consumer::run;
auto pointer_to_object = this;
(pointer_to_object->.pointer_to_member_function)();

Это эквивалентно бегу this->run()

Другие вопросы по тегам