
The design choice between throwing and undefined behaviour (in release builds, where asserts become no-ops) boils down to the choice of who should check the precondition: the callee, or the caller. Tradition has favoured the caller checking the precondition whenever possible, because the caller has more information and can sometimes check more efficiently (e.g. by eliding the check altogether in cases where it already knows the precondition is met).
And sometimes is less efficient. For instance, if you are populating from StaticVector from list iterators (or any non-random access iterators), it's an O(n) check ahead of time or a complicated wrapper around a one-at-a-time insert. (Note: this is a bug in the current implementation of StaticVector, as its iterator constructor currently requires random access iterators).
Does this mean that in any of the functions where I have two iterators, I should separately implement one for boost::single_pass_traversal_tag and another for boost::random_access_traversal_tag? I assume I want to simply check the distance between two random access iterators and return immediately if the size is too big. Then, if it isn't random access I should just start copying and check if I've run out of space on each element that is added. Is this correct? On this topic, what is the difference between boost::random_access_traversal_tag and std::random_access_iterator_tag, and should I implement both? Cheers! Andrew Hundt