I understand the differences between how the methods work; what I want to know is why the single insertion methods without a hint return a pair with a boolean value indicating success, while the methods accepting hints don't return a boolean value indicating whether or not they failed. From what I can tell, if an element already exists in the container, the insertion fails, and the methods accepting hints are no exception.
So, why does one return a bool, and the other does not?
There could be a lot of why questions.
Why did they provide a hint version? The documentation from GCC explains it pretty clearly:
In the case of <code>std::unordered_set</code> and <code>std::unordered_map</code> you need to look through all bucket's elements for an equivalent one. If there is none the insertion can be achieved, otherwise the insertion fails. As we always need to loop though all bucket's elements, the hint doesn't tell us if the element is already present, and we don't have any constraint on where the new element is to be inserted, the hint won't be of any help and will then be ignored.
In the case of <code>std::unordered_multiset</code> and <code>std::unordered_multimap</code> equivalent elements must be linked together so that the <code>equal_range(const key_type&)</code> can return the range of iterators pointing to all equivalent elements. This is where hinting can be used to point to another equivalent element already part of the container and so skip all non equivalent elements of the bucket. So to be useful the hint shall point to an element equivalent to the one being inserted. The new element will be then inserted right after the hint. Note that because of an implementation detail inserting after a node can require to update the bucket of the following node. To check if the next bucket is to be modified we need to compute following node hash code. So if you want your hint to be really efficient it should be followed by another equivalent element, the implementation will detect this equivalence and won't compute next element hash code.
Why does the version that accepts the hint not include a flag indicating if the content was already there?
If you already have the value for the hint (as the docs mention above) "it won't be of any help and will then be ignored." So why provide it? For consistency. There is no penalty for having it, and adding it allows consistency between all eight containers.