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.