C++ 编写可以使用std::vector或std::set的模板
我已经编写了一个异步作业队列类,它已经很好地工作了很长时间。它使用C++ 编写可以使用std::vector或std::set的模板,c++,templates,C++,Templates,我已经编写了一个异步作业队列类,它已经很好地工作了很长时间。它使用std::vector作为底层集合来保存作业,然后按照您的预期在稍后处理它们。当我添加作业时,它会在此向量上执行推回 最近,我决定模板化它所使用的底层集合类型以及我编写它的方式,这应该非常简单。现在宣布如下: template<typename J, typename CollectionT = std::vector<J>> class async_jobqueue { public: 模板 类异步作业
std::vector
作为底层集合来保存作业,然后按照您的预期在稍后处理它们。当我添加作业时,它会在此向量上执行推回
最近,我决定模板化它所使用的底层集合类型以及我编写它的方式,这应该非常简单。现在宣布如下:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
模板
类异步作业队列
{
公众:
这里只有一个障碍,对于向量类型的容器,我想把东西推到集合的末尾,然后调用push_back
,对于settish类型的容器,我想调用insert
。我怎样才能做出调用哪个的编译决定?或者是否有一个方便的适配器可以使用?我宁愿使用一个重载的帮助r函数。下面的函数依赖于一个事实,即没有标准容器同时公开单个参数insert()
函数和push\u 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));
}
#包括
模板
在容器中自动插入(C&C、T&T)->
decltype(c.push_back(std::forward(t)),void())
{
c、 向后推(标准:向前推(t));
}
模板
在容器中自动插入(C&C、T&T)->
decltype(c.insert(std::forward(t)),void())
{
c、 插入(标准:正向(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();
}
#包括
#包括
#包括
int main()
{
std::集s;
std::向量v;
将_插入_容器(s,5);
将_插入_容器(v,5);
std::cout既然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
}
};
模板
类异步作业队列
{
公众:
需要关联容器()
无效添加_函数(常量J和项目){
//使用插入
}
需要序列_容器()
无效添加_函数(常量J和项目){
//使用推回键
}
};
当然,这还不可能(也可能永远不可能)。但是,对concepts lite的接收是非常积极的。插入(迭代器,值类型)
重载并使用end()
调用它怎么样?这两种方式都可用,应该可以做你想做的事情!也适用于std::list
这里真的不需要进行类型分派。请检查:。当我读到它时,它让我大吃一惊。@SirPentor这很酷,尽管它看起来可以让我在运行时计算出来。或者使用SFIANE
()或者专门化或模板。@Benj您可以将其与std::enable_if
或static_asset
结合使用,以便在编译时执行该操作。@Benj您如何确定什么是向量或集合类型的容器?您是指序列容器还是关联容器?您是否使用与之相同的来诱导SFINAE@大卫:是的,这只是一个小把戏。可能还有其他方法可以使用:->decltype(c.insert(std::forward(t)),void())
来减少代码膨胀。@David:是的,这更干净了,让我来编辑答案。谢谢!遗憾的是,尽管g++编译了这个,VC2010却说:w32threads.h(45):错误C2995:'void insert_in_container(C&,T&&'):函数模板已定义
Yes very,看起来既漂亮又干净。