c++ 将reference_wrapper而不是引用传递到std::thread和std::vector [已关闭]

7nbnzgx9  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(144)

已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

2天前关闭。
Improve this question
Reference_wrapper是一个指针的类 Package 器。我错过了一些关于reference_wrapper的动机的基本信息,为什么要引入reference_wrapper,我试图通过以下问题来找到它:
1.将一个简单的指针作为参数传入std::thread会有什么问题?
1.编译器不允许传递一个对象的引用到std::thread。为什么,如果一个简单的引用(地址)被接受(我不是指通过引用传递),在引擎盖下面会出什么问题?
1.我知道要存储在stl容器中的类型必须满足CopyAssignable和CopyConstructible的要求(这就是reference_wrapper所做的),我认为这主要是因为要调整/恢复容器,即std::vector.然而,假设在我们的例子中没有发生调整大小,那么存储引用是否正确?
1.把reference_wrapper存储到一个stl容器中比存储一个简单的指针有什么好处?是不是只有我们知道,这个向量不拥有reference_wrapper所指向的对象,我们必须单独删除它(而不是指针,因为ownersip是不明确的)?

x759pob2

x759pob21#

1.指针可以是nullptr。指针不能代替引用,反之亦然。
1.它不是编译器,它的设计是参数按值传递给线程构造函数

  1. std::vector是一个模板。成员方法只有在实际调用时才被示例化。您可能会构造一个元素类型不满足所有要求的向量,但它可能不是那么有用。细节相当复杂,我认为它们对于这个问题的范围来说太宽泛了。std::reference_wrapper可以存储在std::vector中,没有任何问题。
    1.指针不能代替引用。它们有不同的语义。std::reference_wrapper很可能只是一个指针,但它的行为确实像一个引用。当你需要一个引用时,这就是你想要的。
wgeznvg7

wgeznvg72#

实际上,std::thread的构造函数只能接受引用作为输入参数;但最终所有被引用的对象都被复制到线程的本地缓冲区(栈头),然后再调用辅助函数。原因很简单:引用可能比其被引用对象的寿命长,这会导致运行时错误。如果线程管理器对象存储在超过线程构造范围的容器中,或者线程被分离,则可能发生这种情况。任何需要人为地将引用(如reference_wraper)传输到线程的代码都是可疑的,并且应该避免。原始C指针是现代C++不推荐在用户代码库中使用的麻烦的遗留物。如果你需要在代码中的任何地方使用指针(不仅仅是线程的特殊情况),您可以考虑使用智能指针(std::uniqe_ptrstd::shared_ptr,...)。
最后一个建议:std::jthread优于std::thread;前者在销毁时自动加入,这是对RAII的更好保证。

相关问题