我有一个函数需要接收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());
}
答案 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>