【问题标题】:Generic function to flatten a container of containers扁平化容器容器的通用函数
【发布时间】:2011-09-18 06:59:33
【问题描述】:

我试图更好地掌握迭代器和泛型函数。我认为编写一个将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&lt; ... pages of templates ...

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

【问题讨论】:

  • 请注意,堆栈没有迭代器,也没有开始/结束函数。如果您希望它与堆栈一起使用,您肯定必须对其进行特殊处理。
  • 确实如此;我会换个问题。我实际上并不需要堆栈兼容性;只是可迭代的容器。

标签: c++ templates generics containers


【解决方案1】:

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

#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;
    }
}

【讨论】:

  • SFINAE 不适用于函数体中可能发生的替换失败。它仅适用于函数签名(返回类型和参数)。
  • 这确实是一个错字,但事实证明我也犯了将我的通用函数原型包含在头文件中的错误。我刚刚发现你不能那样做;你必须包含整个 cpp 文件(我认为)。
【解决方案2】:

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;
    });

【讨论】:

    猜你喜欢
    • 2018-01-17
    • 1970-01-01
    • 2021-09-26
    • 2012-07-15
    • 1970-01-01
    • 2020-06-04
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多