Follow the STL when defining a container
Reason
The STL containers are familiar to most C++ programmers and a fundamentally sound design.
Note
There are of course other fundamentally sound design styles and sometimes reasons to depart from the style of the standard library, but in the absence of a solid reason to differ, it is simpler and easier for both implementers and users to follow the standard.
In particular, std::vector and std::map provide useful relatively simple models.
Example
// simplified (e.g., no allocators):
template<typename T>
class Sorted_vector {
using value_type = T;
// ... iterator types ...
Sorted_vector() = default;
Sorted_vector(initializer_list<T>); // initializer-list constructor: sort and store
Sorted_vector(const Sorted_vector&) = default;
Sorted_vector(Sorted_vector&&) noexcept = default;
Sorted_vector& operator=(const Sorted_vector&) = default; // copy assignment
Sorted_vector& operator=(Sorted_vector&&) noexcept = default; // move assignment
~Sorted_vector() = default;
Sorted_vector(const std::vector<T>& v); // store and sort
Sorted_vector(std::vector<T>&& v); // sort and "steal representation"
const T& operator[](int i) const { return rep[i]; }
// no non-const direct access to preserve order
void push_back(const T&); // insert in the right place (not necessarily at back)
void push_back(T&&); // insert in the right place (not necessarily at back)
// ... cbegin(), cend() ...
private:
std::vector<T> rep; // use a std::vector to hold elements
};
template<typename T> bool operator==(const Sorted_vector<T>&, const Sorted_vector<T>&);
template<typename T> bool operator!=(const Sorted_vector<T>&, const Sorted_vector<T>&);
// ...
Here, the STL style is followed, but incompletely. That's not uncommon. Provide only as much functionality as makes sense for a specific container. The key is to define the conventional constructors, assignments, destructors, and iterators (as meaningful for the specific container) with their conventional semantics. From that base, the container can be expanded as needed. Here, special constructors from std::vector were added.
Enforcement
???