我有一个函数需要接收std::list
或std::vector
MyClass *
对象,并根据里面的内容做一堆处理。我不想复制函数体。
我只需要使用这些对象迭代它们并进行一些只读检查。
我曾想过直接传递.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());
}
您可以使用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引用(The const &
)获取ListOrVector。这样可以防止复制。
编辑
我修复了第二个例子。缺少ListOrVector之前的qazxswpo,默认情况下分配器是class
。
就像普通函数一样,函数模板也可以重载,这样你就可以充分利用这两个方面:基于迭代器的算法可以提供更大的灵活性,基于容器的算法更易于使用。
这样,您可以使用基于迭代器的重载来处理容器的子范围,使用基于容器的重载来处理容器的所有元素。
std::allocator<My
我建议首先定义一个函数模板process(first, last)
,它为你想要处理的元素序列采用迭代器对:
process()
这是一个基于迭代器的算法(即,它需要一个迭代器对),并且对应于STL算法遵循的相同方法。
template<typename Iterator>
void process(Iterator begin, Iterator end) {
for (auto it = begin; it != end; ++it) {
// ...
}
}
然后,我将定义另一个重载第一个的函数模板process(container)
。这个重载需要一个容器,并在传递的容器的元素上调用基于迭代器的process()
版本:
process()
这是一个基于容器的算法,因为它需要一个容器。
这样,您可以使用基于容器的算法而不是基于迭代器的算法:
template<typename Container>
void process(Container const& c) {
process(std::begin(c), std::end(c));
}
这个算法与要处理的容器分离(例如,它甚至可以用于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);
的重载。