You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost Range是否支持相邻元素转换?有无对应适配器?

Boost Range处理相邻元素转换的方案

好问题!Boost Range本身并没有直接提供专门用于转换相邻元素对的适配器,但我们有两种靠谱的解决办法:一种是用现有适配器组合实现,另一种是自定义适配你需求的适配器。

方案一:用现有适配器组合(推荐)

Boost Range的boost::adaptors::sliding适配器可以生成指定大小的滑动窗口,我们把窗口大小设为2,就能得到所有相邻元素对,再配合transformed适配器对每个窗口应用二元函数即可。

示例代码如下:

#include <vector>
#include <iostream>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

int main() {
    std::vector<int> a = {1, 2, 3};
    
    // 生成大小为2的滑动窗口,每个窗口包含相邻的两个元素
    auto adjacent_windows = a | boost::adaptors::sliding(2);
    // 对每个窗口应用求和函数
    auto result = adjacent_windows | boost::adaptors::transformed([](const auto& window) {
        return window[0] + window[1];
    });
    
    // 输出结果
    boost::range::copy(result, std::ostream_iterator<int>(std::cout, ", "));
    // 输出:3, 5, 
}

这个方法不需要自己写额外的迭代器或适配器,利用现有组件就能快速实现需求,代码可读性也不错。

方案二:自定义transform_adjacent适配器

如果你想要更直观的接口(就像你示例里写的a | boost::range::transformed([](int x, int y){return x+y;})这种形式),可以自己实现一个专门的适配器。

下面是完整的自定义适配器实现,基于Boost Range的迭代器适配器框架:

#include <vector>
#include <iostream>
#include <boost/range/adaptors.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/iterator_adaptor.hpp>

// 自定义迭代器:遍历相邻元素对并应用二元函数
template <typename Iterator, typename BinaryFunc>
class transform_adjacent_iterator
    : public boost::iterator_adaptor<
          transform_adjacent_iterator<Iterator, BinaryFunc>,
          Iterator,
          typename std::result_of<BinaryFunc(typename Iterator::value_type, typename Iterator::value_type)>::type,
          boost::use_default,
          typename std::result_of<BinaryFunc(typename Iterator::value_type, typename Iterator::value_type)>::type>
{
public:
    transform_adjacent_iterator() = default;
    transform_adjacent_iterator(Iterator it, BinaryFunc func)
        : transform_adjacent_iterator::iterator_adaptor_(it), func_(std::move(func)) {}

private:
    friend class boost::iterator_core_access;
    
    // 解引用时获取当前元素和下一个元素,应用函数
    typename transform_adjacent_iterator::reference dereference() const {
        Iterator next = this->base();
        ++next;
        return func_(*this->base(), *next);
    }
    
    // 每次迭代向前移动一位
    void increment() {
        ++this->base_reference();
    }
    
    // 终止条件:当前迭代器的下一个元素是范围的末尾
    bool equal(const transform_adjacent_iterator& other) const {
        Iterator next = this->base();
        ++next;
        Iterator other_next = other.base();
        ++other_next;
        return next == other_next;
    }
    
    BinaryFunc func_;
};

// 适配器包装类,用于存储二元函数
template <typename BinaryFunc>
struct transform_adjacent_adaptor {
    BinaryFunc func;
    explicit transform_adjacent_adaptor(BinaryFunc f) : func(std::move(f)) {}
};

// 工厂函数,方便创建适配器
template <typename BinaryFunc>
transform_adjacent_adaptor<BinaryFunc> transform_adjacent(BinaryFunc f) {
    return transform_adjacent_adaptor<BinaryFunc>(std::move(f));
}

// 重载|运算符,让Boost Range识别我们的适配器
template <typename Range, typename BinaryFunc>
auto operator|(Range&& r, transform_adjacent_adaptor<BinaryFunc> adaptor) {
    using Iterator = typename boost::range_iterator<Range>::type;
    using Iter = transform_adjacent_iterator<Iterator, BinaryFunc>;
    return boost::make_iterator_range(
        Iter(boost::begin(r), adaptor.func),
        Iter(boost::end(r), adaptor.func)
    );
}

// 使用示例
int main() {
    std::vector<int> a = {1, 2, 3};
    // 现在可以像你预期的那样使用了
    auto result = a | transform_adjacent([](int x, int y) { return x + y; });
    
    for (int val : result) {
        std::cout << val << ", ";
    }
    // 输出:3, 5, 
}

这个自定义适配器完全符合你想要的使用方式,接口更直观,适合频繁使用这类操作的场景。

内容的提问来源于stack exchange,提问作者bradgonesurfing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:41:28