How to write a function that takes any STL container as an argument in C++
STL containers take two template arguments, the type T
inside the container and the allocator (which defaults to std::allocator<T>
).
Therefore to write a function that takes any STL-like container, you have to do it like in this example function:
/**
* Convert any STL-like container to a std::vector.
*/
template<template<typename, typename> typename Container, typename T, typename Allocator>
std::vector ToVector(const Container<T, Allocator>& args) {
std::vector ret;
ret.reserve(args.size());
for(const T& arg : args) {
ret.push_back(arg);
}
return ret;
}
This function can take any STL-like container like std::list
, std::vector
and also STL-compatible containers from third-party libraries and convert it to a std::vector
.
Full example:
#include <list> // std::list
#include <vector> // std::vector
#include <iostream> // std::cout, std::endl
using namespace std;
/**
* Convert any STL-like container to a std::vector.
*/
template<template<typename, typename> typename Container, typename T, typename Allocator>
std::vector ToVector(const Container<T, Allocator>& args) {
std::vector ret;
ret.reserve(args.size());
for(const T& arg : args) {
ret.push_back(arg);
}
return ret;
}
int main() {
// Create list
list myList;
myList.push_back(2);
myList.push_back(3);
myList.push_back(5);
// Convert to vector
vector myVector = ToVector(myList);
// Print vector - should print 2, 3 & 5
for(int val : myVector) {
cout << val << endl;
}
}
Thanks to Jesse Good on StackOverflow for publishing hints on how to solve this problem. However, his version only works with STL containers that use std::allocator
and not with STL containers without custom allocators. In my experience it’s very rare that you have to use a custom allocator, but if you do, it’s very hard to debug why the template doesn’t match.