我无法编译以下程序。
void toSin(std::list<double>&& list)
{
std::for_each(list.begin(), list.end(), [](double& x)
{
x = sin(x);
});
}
int main()
{
std::list<double> list;
const double pi = 3.141592;
const double epsilon = 0.0000001;
for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi / 16)
{
list.push_back(x);
}
// Start thread
std::thread th(toSin, std::move(list));
th.join();
return 0;
}
我得到&gt;错误C2664:“void (std::list<double,std::allocator<_Ty>> &&)
”:无法将参数1从“std::list<double,std::allocator<_Ty>>
”转换为“std::list<double,std::allocator<_Ty>> &&
”
答案 0 :(得分:0)
我觉得你的编译器错了。衰减(复制)值类型应该可绑定到右值引用。
无论如何看看this quote from the documentation
3)创建新的std :: thread对象并将其与执行线程相关联。新的执行线程开始执行
std::invoke(decay_copy(std::forward<Function>(f)), decay_copy(std::forward<Args>(args))...);
基本上,作为参数传递给std::thread
的构造函数的任何内容都将作为函数参数复制到函数中。
另外要知道,如果您按函数而不是通过右值引用接受std::list
变量,那么您的函数将正常工作。有关详情,请参阅Correct usage of rvalue references as parameters
如果你的意图是将对变量的引用传递给线程函数,那么我的方式通常是使用lambda
std::list<double> lst;
auto th = std::thread{[&lst]() {
toSin(lst);
}};
但您也可以使用std::ref
获得相同的效果。我个人觉得lambda方法更清晰。
std::list<double> lst;
auto th = std::thread{toSin, std::ref(lst)};
Also as correctly pointed out in the comments,您的代码中存在竞争条件,您应该使用mutex
阻止,或等待线程完成
auto th = std::thread{[&lst]() {
toSin(lst);
}};
th.join();
// then iterate and print out
答案 1 :(得分:0)
我认为您可能会错过一些#include
,该代码适用于Visual Studio 2015
#include <algorithm>
#include <list>
#include <thread>
void toSin(std::list<double>&& list)
{
std::for_each(list.begin(), list.end(), [](double& x)
{
x = sin(x);
});
}
int main()
{
std::list<double> list;
const double pi = 3.141592;
const double epsilon = 0.0000001;
for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi / 16)
{
list.push_back(x);
}
// Start thread
std::thread th(toSin, std::move(list));
th.join();
return 0;
}