If I have the following program:
#include <vector>
#include <set>
template<class T, class U>
void AddToContainer(T& container, U value)
{
container.push_back(value);
}
int main(char**, int)
{
std::vector<int> v;
AddToContainer(v, 1);
std::set<int> s;
AddToContainer(s, 1);
return 0;
}
How can I make the adding to the container generic? Since std::set
hasn't got a push_back
but only insert
, this will fail to compile.
Containers in C++ STL (Standard Template Library) Last Updated: 12-07-2020 A container is a holder object that stores a collection of other objects (its elements).
A container is a holder object that stores a collection of other objects (its elements). They are implemented as class templates, which allows a great flexibility in the types supported as elements.
Syntax 3: Inserts the characters of the C-string cstr so that the new characters start with index idx. string& string::insert (size_ type idx, const char* cstr) idx : is the index number where insertion is to be made. *cstr : is the pointer to the C-string which is to be inserted.
They are implemented as class templates, which allows great flexibility in the types supported as elements. The container manages the storage space for its elements and provides member functions to access them, either directly or through iterators (reference objects with similar properties to pointers).
You could use expression SFINAE with a dummy parameter to check if push_back()
works:
template <class C, class V>
auto append(C& container, V&& value, int)
-> decltype(container.push_back(std::forward<V>(value)), void())
{
container.push_back(std::forward<V>(value));
}
template <class C, class V>
void append(C& container, V&& value, ...)
{
container.insert(std::forward<V>(value));
}
which your function will just forward to:
template <class C, class V>
void AddToContainer(C& container, V&& value) {
append(container, std::forward<V>(value), 0);
}
If push_back()
is a valid expression, the first overload will be preferred since int
is a better match for 0
than ...
If push_back()
isn't a valid expression, then there's only one viable overload.
Whether this is actually a good idea or not is a separate question.
I believe that all* C++ containers (though not the container adapters like priority_queue
) have a version of insert that looks like this:
iterator insert(iterator location, T&& value)
For the sequence collections, the location is the actual location; for associative collections (like map
and unordered_map
), the iterator is a "hint" parameter (for instance, to help a map
insert an element quickly if you already know precisely where it belongs in sorted order). However, providing an invalid hint doesn't cause any invalid behavior, so a valid generic insert for C++ collections would be:
template<C, T>
void insert(C& collection, T&& value) {
collection.insert(collection.end(), std::forward<T>(value));
}
* It looks like forward_list
is the only one that doesn't have this method, which makes sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With