#include <vector>
#include <iostream>
#include <memory>
int main()
{
// create the vector
std::vector< std::unique_ptr< int > > v;
for ( int i = 0; i < 5; ++ i )
{
std::unique_ptr< int > newItem( new int(i) );
v.push_back( std::move( newItem ) );
}
std::cout<<"vector's size before the move = " << v.size() << std::endl;
// move one item
auto it = move( v[2] );
std::cout<<"moved element = " << *it << std::endl;
std::cout<<"vector's size after the move = " << v.size() << std::endl;
if ( nullptr == v[2].get())
std::cout<<"it is nullptr" << std::endl;
}
The above example is moving one element out of the vector, but the vector’s size remained the same.
What contains the moved element after the move? Is it an undefined behaviour to access that element? Is it nullptr (the example prints it is null)?
It’s nothing to do with the vector.
std::uniqe_ptrdefines the state of the object after a move, it’s set to null (20.7.1/4).In general, an object that has been moved from has a valid but unspecified state. So unless the type documents cases in which it cannot be accessed, you can access it. Particular classes arguably should give more detail of that state whenever possible, but what vector relies on is that:
So, for a type other than
unique_ptrin the vector, you should probably think to yourself that the resulting value of the source of the move can be any of:If you still think it’s worth accessing a value that might be any of those, go ahead 😉