我编写了一个异步作业队列类,它已经很好地工作了很长时间。它使用std::vector
作为底层集合来保留作业,然后按照您的预期稍后处理它们。当我添加作业时,它会在push_back
上执行vector
。
最近我决定要模仿它使用的底层集合类型以及我编写它的方式,这应该非常简单。现在宣布:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
只有一个障碍,对于矢量型容器,我想把东西推到集合的末尾并调用push_back
,对于我想要调用insert
的定居类型容器。如何做出关于调用哪个的编译决定?或者我可以使用一个方便的适配器吗?
答案 0 :(得分:5)
我宁愿使用重载的辅助函数。下面的内容依赖于以下事实:没有标准容器暴露单参数insert()
函数和push_back()
函数:
#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));
}
这就是你如何使用它们:
#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();
}
这是一个live example。
答案 1 :(得分:3)
insert(iterator, value_type)
重载怎么样,并用end()
调用它?它可用于两者,应该做你想要的!也适用于std::list
!
这里真的不需要进行类型调度。
答案 2 :(得分:2)
由于concepts-lite有希望及时出现在C ++ 14中,我不妨告诉你如何做到这一点:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
requires Associative_container<CollectionT>()
void adding_function(const J& item) {
// Uses insert
}
requires Sequence_container<CollectionT>()
void adding_function(const J& item) {
// Uses push_back
}
};
当然,这还不可能(也可能永远不会)。然而,接受Concepts-lite是非常积极的。