Many also need to learn that there are configuration settings on their compilers that make those two cases the same, enabling bounds checking on operator[]().
Sure, but at() is guaranteed to throw an exception and operator[] can throw an exception when you go out of bounds. C++26 is tweaking this, but it's still going to differ implementation to implementation.
At least that's my understanding of the situation. Happy to be corrected though.