迭代包含向量的解除引用unique_ptr,用于范围循环
问题描述:
为什么不按照我的假设工作?迭代包含向量的解除引用unique_ptr,用于范围循环
for (auto it: *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})))
std::cout << it << std::endl;
的矢量对象执行循环的第一次迭代之前销毁
答
的range-based for loop等同于:
{
init-statement
auto && __range = range_expression ;
...
}
为了您range_expression,这将是
auto && __range = *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5}));
但是
如果range_expression返回一个暂时的,它的寿命被延长,直到循环的结束时,通过结合到右值参考
__range
所指示的,但要注意,任何临时的range_expression内的寿命不延伸。
什么std::make_unique
返回的是一个临时std::unique_ptr
,充分表达它会被销毁后。这意味着它所管理的std::vector
也会被销毁;即使从临时std::unique_ptr
获得的std::vector
绑定到转发参考,其生存期也不会延长。
从C++ 20开始,你可能会使用init语句;如
for (auto p = std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); auto it : *p)
std::cout << it << std::endl;
注意,C++ 20允许避免经由“基于范围与初始化语句”这种缺陷的,如下所述:https://herbsutter.com/2017/11/11/行程报告下落-ISO-C-标准的会议阿尔伯克基/。也就是说:你将独立地声明'unique_ptr',确保它在整个循环中生存,然后使用它的取消引用作为迭代的范围。 –
为什么不简单写'for(auto it:{1,2,3,4,5})'?对于更复杂的情况,为什么'std :: unique_ptr>'而不是'std :: vector ''。 –
Jarod42
是的,这是一个非常人为的例子,它展示了问题领域,但有点夸张的方式。 :) –