I'll start with the Range concept.
A range has only two methods: start and end. They both return iterators of the same type (note: there are suggestions allowing the end to return Sentinel).
Iterators are considered understandable to the reader.
The high-quality range can also expose empty, size, front, back and operator [] (especially for random access).
For a for(:) loop, you can qualify as a Range , being a raw C array having begin() and end() methods or having free functions in the same namespace as your type, which takes your type as one argument (and return iterative stuff). Starting with this post, the only thing used in the standard that uses ranges is for(:) loops. It can be argued that this answer is the only practical definition of the concept of Range in C ++.
Next, the container.
A container is a range of at least forward iterators (input and output ranges are usually not called Containers) to which its elements belong. Serial and associative containers are different animals, and both are defined in the standard.
Containers in the standard have a set of typedefs - value type, iterator, const iterator. Most also have a dispenser (other than an array). They are empty, and most of them have a size (except forward_list).
Containers can be constructed using 2 input or redirect iterators to a compatible value type and from the list of initializers.
Serial containers have push and emplace back (except for the forward list) (and some have emplace / push front), and also insert and replace on the iterator (or after for the forward list).
Associative containers have a key type. Many of them are containers with vapors. Stored data is usually partially const (the โkeyโ part of the data, whether it is a key or full field in the case of set s). They insert and place with and without tips - they manage their own order. They also have .find and .count .
There are no functions dependent on Container-ness in the std library. And there is an active suggestion that the Container and Range are formalized as a concept in C ++ 17. The actual technical definition of Container meets the standard if you need to accurately create a real container; however, as a rule, you really need a Range with tools for editing it and mechanics of ownership. The container concept, in my experience, is mainly there to simplify the definition of behavior in the standard.
After adding something like Ranges-v3, the Range and Container concepts will be real things that exist in the code, and there may be algorithms that depend on exactly these functions. Prior to this, they are ad-hoc concepts more than anything else.