问题
I've done quite a bit of research on the new c++11 rvalue and carried over lvalue. Here is a sample of what I have found and read:
what-does-t-double-ampersand-mean-in-c11
how-stdthread-constructor-detects-rvalue-reference
stdthread-and-rvalue-reference
I have also briefed myself on rvalue references
Move_Semantics
rvalue_references
A Proposal to Add an Rvalue Reference to the C++ Language
Specifically, regarding the std::thread
constructor, I found
how-to-create-a-thread-inside-a-class-function
and used one of the answers to write some simple code
#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
Checking the `std::thread constructor
std::thread::Thread
I observe a template that uses rvalue parameters. I understand that a std::thread
can be initiated through a simple example
void run(void) {std::cout << "I'm running";}
std::thread(run);
which appears straight-forward until I am inside a class whereby I need to do the following
consumer = std::thread(&Consumer::run, this); <-- need understanding
because I learned from Jonathan Wakely that run() is a non-static member function and has to be run on an object. How is the new thread supposed to know which object to call it on if you don't tell it?
This makes some sense but the need to pass by reference the class function doesn't since I have seen A a; A&& ref = A()
possible. I'm super confused about rvalues and just want to understand why the code I wrote above is necessary to pass the function to std::thread
.
I feel certain I also don't understand variadic templates that well either which compounds my understand of the std::thread
variadic template constructor.
回答1:
I observe a template that uses rvalue parameters.
No, the std::thread
constructor uses forwarding references, which means they can accept any type of argument and deduce either lvalue or rvalue references, depending on the argument type.
Read forwarding references and Universal References in C++11 (Scott Meyers introduced the name "universal reference" for these, but the official name is now "forwarding reference").
This makes some sense but the need to pass by reference the class function doesn't
You're confused, &Consumer::run
is not a reference of any kind. The symbol &
as part of a typename means a reference, but when it apepars on the left of an expression it is the "address of" operator, which forms a pointer. In this case it is forming a pointer to member function.
The expression std::thread(&Consumer::run, this)
constructs a thread with two arguments, a pointer to the member function that should run in the new thread, and a pointer to the object that the member function will be called on. So in the new thread, something like this happens:
auto pointer_to_member_function = &Consumer::run;
auto pointer_to_object = this;
(pointer_to_object->.pointer_to_member_function)();
This is equivalent to running this->run()
来源:https://stackoverflow.com/questions/46698832/stdthread-constructor-pass-by-reference-when-using-a-class-member-function