T&& operator[](std::size_t n) && noexcept {std::cout<<"move"<<std::endl; return std::move(vec[n]); }
I cannot get the expected result in this part.
I predict a dangling reference happens.
T operator[](std::size_t n) && noexcept {std::cout<<"move"<<std::endl; return std::move(vec[n]); }
This works well.
Why doesn't T&& increase lifetime?
#include <iostream>
#include <stdlib.h>
#include<vector>
template<typename T, typename Alloc = std::allocator<T>>
class my_vector
{
std::vector<T, Alloc> vec;
public:
my_vector(std::initializer_list<T> init) : vec{init} {}
T&& operator[](std::size_t n) && noexcept {std::cout<<"move"<<std::endl; return std::move(vec[n]); } // moveしたものを参照するとごみを参照してることになる
//T operator[](std::size_t n) && noexcept {std::cout<<"move"<<std::endl; return std::move(vec[n]); }
};
int main()
{
auto&& vec = my_vector<int>{1, 2, 3}[0]; //case3 move
std::cout<<vec<<std::endl; //0
}
CodePudding user response:
For auto&& vec = my_vector<int>{1, 2, 3}[0];
, the reference isn't bound to the temporary (i.e. my_vector<int>{1, 2, 3}
) directly, its lifetime won't be extended.
In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference variable or data member to which the temporary was bound, does not affect its lifetime.
On the other hand, if you change the return type of operator[]
to T
, then what it returns (i.e. my_vector<int>{1, 2, 3}[0]
) is a temporary and gets bound to vec
, then its lifetime is extended to the lifetime of vec
.