定义一个函数,使其可以接受列表或向量

时间:2019-03-09 20:19:00

标签: c++ stl

我有一个函数需要接收std::list个对象的std::vectorMyClass *,并根据内部内容进行一堆处理。 我不想复制函数主体。

我只需要使用这些对象来遍历它们并进行一些只读检查。

我曾经考虑过直接传递.begin().end()迭代器,但这看起来一点也不漂亮。

是否有更好的方法来解决此问题,目前我有以下解决方案(该方法从要传递的向量中创建另一个列表,这也不是很理想)。

void process(std::list<MyClass*> input)
{
    //A lot of processing
    BOOST_FOREACH(MyClass* itMyClass, input)
    {
        //some checks, creating new list based on the checks      
    }
    //A lot of processing
}
void process(std::vector<MyClass*> input)
{
    process(std::list<MyClass*>(input.begin(), input.end()));
}

编辑:

似乎很多人建议毕竟使用begin()end(),我使它的工作方式类似于下面的示例。感谢您的帮助。

//This one is private
template <typename Iterator>
void process(Iterator begin, Iterator end)
{
    //A lot of processing
    for (; begin != end; ++begin) 
    {
        //some checks, creating new list based on the checks
    }
    //A lot of processing
}
void process(std::list<MyClass*> input)
{
    process(input.begin(), input.end());
}
void process(std::vector<MyClass*> input)
{
    process(input.begin(), input.end());
}

2 个答案:

答案 0 :(得分:4)

您可以使用function template

template<class ListOrVector>
void process(ListOrVector const& input) {
    //your code
}

//You can also use a template template parameter
template<template<class My, class Alloc = std::allocator<My>> class ListOrVector>
void process(ListOrVector<MyClass*, Alloc> const& input) { ... }

请注意,我通过const引用(const &)获取ListOrVector。这样可以防止复制。

编辑

我已经解决了第二个例子。缺少ListOrVector之前的class,默认情况下分配器为std::allocator<My

答案 1 :(得分:0)

就像普通功能一样,功能模板也可以重载,这样您就可以兼得两全:基于迭代器的算法以提供更大的灵活性,并使用基于容器的 来简化操作。

这样,您可以使用基于迭代器的重载来处理容器的子范围,并使用基于容器的重载来处理容器的所有元素。


process(first, last)

我建议首先定义一个函数模板process(),该模板需要一个 iterator对用于要处理的元素序列:

template<typename Iterator>
void process(Iterator begin, Iterator end) {
   for (auto it = begin; it != end; ++it) {
      // ...
   }
}

这是基于 iterator的算法(即,它需要一个迭代器对),并且与STL算法遵循的相同方法相对应。


process(container)

然后,我将定义另一个函数模板process(),该模板重载第一个模板。此重载占用一个容器,并在传递的容器的元素上调用process()的基于迭代器的版本:

template<typename Container>
void process(Container const& c) {
   process(std::begin(c), std::end(c));
}

这是一个基于容器的算法,因为它需要一个容器。


这样,您可以使用基于容器的算法,而不是基于迭代器的算法:

std::vector<int> vec{1, 2, 3};
std::list<int> lst{1, 2, 3};
std::array<int, 3> arr{1, 2, 3};
int carr[] = {1, 2, 3};

process(vec);
process(lst);
process(arr);
process(carr);

此算法从容器中分离出来进行处理(例如,它甚至可以用于C样式的数组,如您所见),但是您可以直接在容器上调用它,而无需传递迭代器。

如果您不想处理容器的所有元素,而只是处理其中的一部分子元素,则可以随时调用process()的重载,该重载使用迭代器对代替容器。 / p>