7

我编写了一个异步作业队列类,它已经很好地工作了很长时间。它使用 astd::vector作为基础集合来保存作业,然后按照您的预期处理它们。当我添加一份工作时,它会push_back对此进行处理vector

最近我决定要模板化它使用的底层集合类型以及我编写它的方式,这应该非常简单。现在这样声明:

template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:

只有一个障碍,对于矢量类型的容器,我想将东西推到集合的末尾并调用push_back,对于设置类型的容器,我想调用insert。我怎样才能做出关于调用哪个编译的决定?或者有没有我可以使用的方便的适配器?

4

3 回答 3

7

我宁愿使用重载的辅助函数。下面的一个依赖于没有标准容器同时公开单参数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();
}

这是一个活生生的例子

于 2013-03-22T15:58:57.817 回答
3

insert(iterator, value_type)重载和调用它怎么end()样?它在两者中都可用,应该做你想做的事!也可以使用std::list

这里真的不需要类型调度。

于 2013-03-22T16:19:11.997 回答
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 的接受度是相当积极的。

于 2013-03-22T16:05:00.870 回答