Sorry, but I don't consider shutting down like that to be "graceful".
Shutting down like "what"?
For instance, you may lose your current document because memory is in an unstable state.
Yes, that would indeed be ungraceful. I don't condone bad design that is prone to losing data.
You may not be able to open a file save dialog, or even write a dump file to disk.
That's true. If you want to do things that require resources when you have run out of resources, you need to plan for it instead of expecting to be able to acquire those resources when the time comes.
You can't really put a try/catch around everything that could possibly allocate some memory. It would make your code virtually unreadable, and difficult to maintain.
From a C++ perspective, if you are writing try/catch on a regular basis, you probably are making poor use of RAII, and you might as well be using return codes. Lots of try/catch clauses in a C++ program is a red flag of cluelessness until proven otherwise.
And exiting with an unhandled exception is hardly graceful, even if it does clean up after itself as much as it can...
For an exception occurring in a typical Windows program, you would end up at the top of your message loop, and there would be an attempt to notify the user of the problem, say, with a MessageBox. That would be the most basic response. For a C++ program, if you have made effective use of RAII, the program will be in a well-defined state, and there's a good chance you will not have written a single try/catch.
When I said, "For some programs, terminating immediately might be an acceptable "graceful" response," I was thinking of programs that aren't modifying persistent data. I wasn't saying this was appropriate for all programs.
Basically, most experts say it's fruitless to check most memory allocations. Yes, large allocations can be beneficial, such as knowing if you can load a large bitmap into memory... but that kind of memory failure is different from a memory exhaustion situation.
But if your position is that it's fruitless to check because you can't do anything about it, then you should terminate right away.
When a memory allocation fails, something is going to happen afterwards. You can (a) anticipate, detect, and deal with it in various ways, (b) detect it and terminate right away, or (c) ignore it and stumble along as if nothing happened until you finally crash somewhere down the line, maybe corrupting something along the way that wouldn't have happened if you had done (a) or (b). It seems to me you're arguing for (c), because you've said (a) is impossible, (b) is "ungraceful", and I don't see what else is left but (c).