I assume that there's a reason for having a convention rather than an actual contract. It seems odd to me that you wouldn't specify that "I am a container, and do the things that containers do" rather than just implementing the necessary methods and _not_ declaring that you're doing so.
The "input iterator" concept is just a useful set of features, coupled with the observation that if some classes implement all those features and some algorithms confine themselves to requiring just those features then they'll get along usefully together.
Unfortunately, one of the wrinkles is the key distinction between an input iterator and a forward iterator: you can copy a forward iterator and use the copy later to make a second pass through the data, whereas an input iterator is once-only (compare traversing a linked list with reading lines from a TCP socket). This distinction between contexts can't be directly enforced by the compiler. There is an iterator_category mechanism to get around the problem, but it's clunky.
There is also a proposal to extend the language with explicit concepts, but it's typical Stroustrup filth and was rightly rejected from C++0x. In due course, someone will come up with something nice to replace it, I hope.
Unfortunately, one of the wrinkles is the key distinction between an input iterator and a forward iterator: you can copy a forward iterator and use the copy later to make a second pass through the data, whereas an input iterator is once-only (compare traversing a linked list with reading lines from a TCP socket). This distinction between contexts can't be directly enforced by the compiler. There is an iterator_category mechanism to get around the problem, but it's clunky.
There is also a proposal to extend the language with explicit concepts, but it's typical Stroustrup filth and was rightly rejected from C++0x. In due course, someone will come up with something nice to replace it, I hope.