用于展平容器容器的通用功能

时间:2011-06-19 20:09:58

标签: c++ templates generics containers

我试图更好地掌握迭代器和泛型函数。我认为编写一个将container1 < container2 <type> >转换为container3 <type>的函数是一项有用的练习。例如,它应该能够将vector< deque<int> >转换为list<int>

我认为所有容器访问都应该通过迭代器,就像<algorithm>中的函数一样。

这是我的代码:

#include <iterator>
#include <algorithm>

// COCiter == Container of Containers Iterator
// Oiter == Output Iterator
template <class COCiter, class Oiter>
void flatten (COCiter start, COCiter end, Oiter dest)
{
    using namespace std;

    while (start != end) {
        dest = copy(start->begin(), start()->end(), dest);
        ++start;
    }
}

但是当我尝试用以下代码调用它时:

int main ()
{
    using namespace std;

    vector< vector<string> > splitlines;
    vector<string> flat;

    /* some code to fill SPLITLINES with vectors of strings */

    flatten(splitlines.begin(), splitlines.end(), back_inserter(flat));
}

我收到一条巨大的C ++模板错误消息undefined reference to void flatten< ... pages of templates ...

我觉得我的代码太容易编写了,我还需要更多的东西来确保内部容器中的数据类型与输出容器中的数据类型相匹配。但我不知道该怎么做。

2 个答案:

答案 0 :(得分:8)

我发现了这个问题。感谢SFINAE(替换失败不是错误),您的编译器无法找到正确的模板,因为您尝试通过键入operator()(可能是拼写错误)来调用start上的start()。试试这个:

#include <iterator>
#include <algorithm>

// COCiter == Container of Containers Iterator
// Oiter == Output Iterator
template <class COCiter, class Oiter>
void flatten (COCiter start, COCiter end, Oiter dest) {
    while (start != end) {
        dest = std::copy(start->begin(), start->end(), dest);
        ++start;
    }
}

答案 1 :(得分:0)

std::accumulate可以为您完成。您需要将每个内部向量的内容收集到外部向量中。

vector<vector<int>> v_of_v;
vector<int> v = std::accumulate(
    v_of_v.begin(), v_of_v.end(),
    vector<int>(),
    [](vector<int> a, vector<int> b) {
        a.insert(a.end(), b.begin(), b.end());
        return a;
    });