I've written an asynchronous job queue class which has been working nicely for ages. It uses a std::vector
as the underlying collection to keep jobs in and then processes them later as you might expect. When I add a job it does a push_back
on this vector
.
Recently I decided that I wanted to templatize the underlying collection type that it uses and the with way I've written it, this should be very simple. It's now declared thus:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
There's just one snag, for vectorish type containers I want to push things onto the end of the collection and call push_back
, for settish type containers I'll want to call insert
. How can I make a compile decision about which to call? Or is there a handy adapter I can use?
I would rather use an overloaded helper function. The one below relies on the fact that no Standard container exposes both a single-argument insert()
function and a push_back()
function:
#include <utility>
template<typename C, typename T>
auto insert_in_container(C& c, T&& t) ->
decltype(c.push_back(std::forward<T>(t)), void())
{
c.push_back(std::forward<T>(t));
}
template<typename C, typename T>
auto insert_in_container(C& c, T&& t) ->
decltype(c.insert(std::forward<T>(t)), void())
{
c.insert(std::forward<T>(t));
}
This is how you would use them:
#include <set>
#include <vector>
#include <iostream>
int main()
{
std::set<int> s;
std::vector<int> v;
insert_in_container(s, 5);
insert_in_container(v, 5);
std::cout << s.size() << " " << v.size();
}
And here is a live example.
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