std::bind and std::thread share a few design principles. Since both of them store local objets corresponding to the passed arguments, we need to use either std::ref or std::cref if reference semantics is desired:
void f(int& i, double d) { /*...*/ }
void g() {
int x = 10;
std::bind(f, std::ref(x), _1) (3.14);
std::thread t1(f, std::ref(x), 3.14);
//...
}
But I'm intrigued by a recent personal discovery: std::bind will allow you to pass a value in the case above, even though this is not what one usually wants.
std::bind(f, x, _1) (3.14); // Usually wrong, but valid.
However, this is not true for std::thread. The following will trigger a compile error.
std::thread t2(f, x, 3.14); // Usually wrong and invalid: Error!
At first sight I thought this was a compiler bug, but the error is indeed legitimate. It seems that the templated version of std::thread's constructor is not able to correctly deduce the arguments due to the copy decaying requirement (tranforming int& in int) imposed by 30.3.1.2.
The question is: Why not require something similar to std::bind's arguments? Or is this apparent inconsistency intended?
Aucun commentaire:
Enregistrer un commentaire