【问题标题】:Appending ranges in loop在循环中附加范围
【发布时间】:2014-11-19 08:46:25
【问题描述】:

我想将函数返回的范围连接成一个大范围。考虑以下代码:

some_type_i_cant_figure_out bar() {
    typedef std::vector<int>::const_iterator iter;
    std::vector<int> aaa;
    /* fill some data into aaa*/
    some_type_i_cant_figure_out cc;
    for (int i = 0; i < aaa.size(); ++i) {
    std::pair<iter, iter> bbb = foo(aaa, i);
    ccc = boost::join(ccc, bbb);
    }
    return ccc;
}

我想要实现的目标:
aaa 向量很大, foo 可能返回相当大的范围。当然,我可以将范围内所有元素的副本创建到新的整数向量中并返回它。它效率低下,浪费内存和时间。所以我想返回一个 boost::joined_range。在最坏的情况下,我可以使用范围向量,但它太简单而且不那么优雅:) 除了joined_range 不是默认可构造的(这对这个示例实现来说是一个问题)之外,返回值类型是什么?临时变量 (ccc) 类型以及实现上述目标的正确和优雅的方法是什么?

【问题讨论】:

  • aaa 的大小是否已知(或有界?)您要达到什么目的?看起来您只是对向量进行稳定排序...
  • 尺寸未知。更改示例以使其更清晰

标签: c++ visual-studio-2012 boost boost-range


【解决方案1】:

首先,您的代码的最终结果似乎类似于

auto cc(aaa);
boost::stable_sort(cc);

(假设,根据您的示例代码,aaa 包含[0..size()-1) 范围内的整数)

如果您负担得起简单的复制,只需使用反向插入迭代器:

std::vector<int> cc;
for (size_t i = 0; i < aaa.size(); ++i)
    boost::copy(boost::equal_range(aaa, i), back_inserter(cc));

否则,您可以使用any_range 隐藏累积连接:

boost::any_range<int, boost::forward_traversal_tag, int> r;
for (size_t i = 0; i < aaa.size(); ++i)
    r = boost::join(r, boost::equal_range(aaa, i));

Live On Coliru

#include <boost/range/any_range.hpp>
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>

int main() {
    std::vector<int> const aaa { 1,1,1,4,5,5,9,42,42,42,42,42,42 };

    boost::any_range<int, boost::forward_traversal_tag, int> r;
    for (size_t i = 0; i < aaa.size(); ++i)
        r = boost::join(r, boost::equal_range(aaa, i));

    boost::copy(r, std::ostream_iterator<int>(std::cout << "result: ", " "));
}

打印

result: 1 1 1 4 5 5 9

【讨论】:

  • 无论如何,我认为这应该涵盖它:)
  • 对不起,我过于简单的例子欺骗了你。我已经编辑了问题。
  • 所以,将boost::equal_range(aaa,i) 替换为foo(aaa,i) 就完成了:)
  • @kreuzerkrieg 注意简单:我想any_range 使用擦除来发挥它的魔力,这意味着你仍然(逻辑上)有一系列范围,除了现在它可能存储在递归树中范围对象,每个节点可能添加一个虚函数调用,并可能动态分配。 (虚拟调用可能由非常智能的编译器优化,动态分配可能使用小对象缓冲区优化小范围(作为 QoI 问题),但这仍然限制了可组合性范围。) [...]
  • [..] 我想说,剖析一下!而且我强烈怀疑您会发现iterator_range 列表实际上是任何显着规模的最佳解决方案(它表达了意图并符合目的......)
猜你喜欢
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多