gpt4 book ai didi

c++ - 如何将列表传递给线程而不复制它,同时销毁原始列表

转载 作者:行者123 更新时间:2023-12-01 00:11:46 28 4
gpt4 key购买 nike

这段代码创建并执行了一个需要获取std::list<int> data内容的线程。无需复制此列表的内容并将其地址更改为内存。指向列表的指针必须对其他代码保持有效。

创建线程后,原始列表data在主线程中被销毁,所以在这种情况下我不能使用它的地址。

我怎样才能做到这一点?我试过使用右值引用,但我担心如果我以这种方式尝试,我可能会有一个悬空指针。这是我所拥有的:

void func(std::list<int> && data){  // <-- what should go here as an argument?
std::sort(data.begin(), data.end());
// do stuff with data
}

int main(){
{
std::list<int> data;
data.push_back(1);
std::thread(func, std::move(data)).detach();
}
// data destroyed
}

最佳答案

thread 调用的构造函数

std::invoke(decay_copy(std::forward<Function>(f)), 
decay_copy(std::forward<Args>(args))...);

其中 decay_copy 定义如下:
template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }

您正在传递 move(data) 。因为 decay_copy 使用引用转发,所以它返回 T&& ,因为 decay_t 丢弃了常量和引用,新的列表对象是通过使用移动构造函数创建的。所以 data 中的 main 列表被移动到线程构造函数中( thread 将其参数存储在元组上 - 您不需要关心移动数据列表对象的生命周期。现在,问题是您想如何传递/访问移动的 data 列表 func 。通过复制/移动或引用,详情如下)。

现在 invoke 被称为:
invoke (func, temporary list object returned by decay_copy)

这里有两种情况需要考虑:

[1] func 具有签名 func(list<int>&&) ,在这种情况下,您只是通过引用访问移动的列表对象 - 不会调用复制或移动操作。

[2] func 具有签名 func(list<int>) ,在这种情况下,将在列表中调用移动构造函数。如果列表没有移动支持,这里将调用复制操作。

所以使用 list<int>&& ,您将节省一次移动操作。

关于c++ - 如何将列表传递给线程而不复制它,同时销毁原始列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58022162/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com