Why doesn't this code work as I supposed?
for (auto it: *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})))
std::cout << it << std::endl;
The vector object is destroyed before executing the first iteration of the loop
The range-based for loop is equivalent to:
{
init-statement
auto && __range = range_expression ;
...
}
For your range_expression, it would be
auto && __range = *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5}));
But
If range_expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the rvalue reference
__range
, but beware that the lifetime of any temporary within range_expression is not extended.
What std::make_unique
returns is a temporary std::unique_ptr
, after the full-expression it will be destroyed. That means the std::vector
managed by it would be destroyed too; even though the std::vector
got from the temporary std::unique_ptr
is bound to the forwarding reference, its lifetime won't be extended.
From C++20 you might work around using init-statement; such as
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With