微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何合并/连接多个 boost::container::small_vector 并将值作为 boost::any_range 返回?

如何解决如何合并/连接多个 boost::container::small_vector 并将值作为 boost::any_range 返回?

我有多个 boost::container::small_vector 存储在一个 std::vector 中,我想将 small_vectors 中存储的所有值作为 boost::any_range 返回。你有什么想法我该怎么做吗?

解决方法

当然,您可以以一种非常低效的方式完成,而无需自己编写更多代码:

    return boost::accumulate(_storage,R {},[](R&& accum,SV const& sv) { return boost::join(std::move(accum),sv); });

完整演示Live On Godbolt

#include <boost/container/small_vector.hpp>
#include <boost/range/any_range.hpp>
#include <boost/range/join.hpp>
#include <boost/range/numeric.hpp>

#include <fmt/ranges.h>

template <typename T>
struct MyData {
    using SV = boost::container::small_vector<T,10>;
    using R = boost::any_range<T,boost::bidirectional_traversal_tag>;

    R all_view() const {
        return boost::accumulate(_storage,sv); });
    }

    std::vector<SV> _storage;
};

int main() {
    MyData<int> ints { { {1,2,3},{4},{5,6,7} } };

    fmt::print("ints: {}\n",ints.all_view());
}

印刷品

ints: {1,3,4,5,7}
  • 优点:写得快

  • 缺点:

    • 需要最近的 boost 和编译器
    • 为大量子范围生成越来越糟糕的代码:see e.g.

    注意简单性:我想象 any_range 使用擦除来发挥它的魔力,这意味着您仍然(逻辑上)有一系列范围,除了现在它可能存储在范围对象的递归树中,每个节点可能会添加一个虚函数调用,以及可能的动态分配。 (虚拟调用可能由非常智能的编译器优化,动态分配可能使用小对象缓冲区优化小范围(作为 QoI 问题),但这仍然限制了范围的可组合性。)

替代方案:

如果可以,请考虑具有 yield_from 的 RangeV3,它可以有效地展平范围,因为它不执行类型擦除。

或者,您可以编写自己的扁平化迭代器。这是更多的工作,但可以通过 boost 进行管理,并将为您提供最佳的预期性能。

Live Demo

#include <boost/container/small_vector.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/optional.hpp>

#include <fmt/ranges.h>

template <typename T>
struct MyData {
    using SV = boost::container::small_vector<T,10>;
    std::vector<SV> _storage;

    struct const_iterator : boost::iterator_facade<const_iterator,T const,boost::forward_traversal_tag> {
        using outer = typename std::vector<SV>::const_iterator;
        using inner = typename SV::const_iterator;

        const_iterator(const_iterator const&) = default;
        const_iterator& operator=(const_iterator const&) = default;

        const_iterator(outer f,outer l) : _outer(f),_last(l) {
            if (_outer != _last)
                _inner = _outer->begin();
            forward_transport();
        }

        const_iterator(outer f = {}) : const_iterator(f,f) {}

        bool equal(const_iterator const& other) const {
            return _outer == other._outer && _inner == other._inner;
        }

        void increment() {
            assert(_outer != _last && _inner != _outer->end());
            ++_inner;

            forward_transport();
        }

        decltype(auto) dereference() const {
            assert(_outer != _last);
            return *_inner;
        }

    protected:
        void forward_transport() { // skip over empty subrange(s)
            while (_outer != _last && _inner == _outer->end()) {
                ++_outer;

                if (_outer == _last)
                    _inner = {};
                else
                    _inner = _outer->begin();
            }
        }
        
        outer _outer,_last;
        inner _inner = {};
    };

    const_iterator begin() const { return {_storage.begin(),_storage.end()}; }
    const_iterator end()   const { return {_storage.end(),_storage.end()}; }
};

int main() {
    MyData<int> ints { { {},{},{ 1,3 },{ 4 },{ 5,7 },{} } };

    fmt::print("ints: {}\n",ints);
}

打印(再次/静止):

ints: {1,7}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?