The erase-remove idiom that jonnin mention is useful when you want to remove all elements that are equal to some object (in which case you use std::remove) or that satisfy some condition (in which case you use std::remove_if).
Since you haven't defined a == operator for you struct you would have to use std::remove_if.
1 2
// Remove all persons with an age less than 30
parr1.erase(std::remove_if(parr1.begin(), parr1.end(), [](const Person& p){ return p.age < 30; }), parr1.end());
If you're using C++20 you don't need to use the erase-remove idiom. You can use std::erase/std::erase_if instead.
1 2
// Remove all persons with an age less than 30
std::erase_if(parr1, [](const Person& p){ return p.age < 30; });
To remove a single element you can pass an iterator to the erase member function.
1 2
// Remove the person at index 1
parr1.erase(parr1.begin() + 1);
Iterators work similar to pointers. parr1.begin() gives you an iterator to the first element and by adding an index (integer) we get an iterator that refers to the element at that index. You cannot pass the index directly to erase because it only accepts iterators.