I think that the whole point of having the at() member function was to provide a version of accessing by index that throws out_of_range for an invalid index. If not for this, they should have scrapped it and just let operator perform the index check and throw exceptions.Yes, which is why I like a choice. I don't like the idea that just because I use the index operator instead of at(), I forgo any such out of bounds checks. If at does it, then the index operator should too.
The way I see it, the design choice is to allow the user of the class the choice by selecting the appropriate function. If you always want an invalid index to result in an exception being thrown, then always use at().