Denis Koroskin wrote:
My point is, if empty() returns false (and you can't know it because
empty() is not const) you may get either an invalid result, access
violation or an exception on member access:
void foo(Range)(const Range r)
{
// is r empty? can I /safely/ access its head?
// let's cross our fingers and try it
// hoping that it is either not empty or throws an exception
auto head = r.head;
...
}
Then it's good design to implement empty() as const. In some cases, you
might not be able to (I believe someone mentioned IO streams as such a
case). There, empty() might also throw.