> The whole point of classes like std::vector and std::string is that they do the memory allocations for you, and also handle cleanup. But that makes it a lot harder to do something sensible if the allocation fails.
No, it actually makes it easier. You don't have to check every operation that needs to allocate memory, and you don't have to manually clean up what has been allocated already when an allocation fails.
> If I can't create a std::string without getting an exception, that means I can't use std::string in a destructor.
If you need to allocate memory dynamically in a destructor, that's tough, but it doesn't make destructors less useful in the 95% of all cases where you don't.