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

adjacent_difference结合back_inserter插入vector<vector<int>>编译失败求助

解决std::adjacent_difference配合返回vector<int>的diff函数插入vector<vector<int>>的问题

看起来你遇到的核心问题是:当std::adjacent_difference调用返回std::vector<int>的自定义diff函数时,std::back_inserter无法正确插入到std::vector<std::vector<int>>中,但返回int时却能正常工作。这其实是adjacent_difference的语义特性导致的类型不匹配问题,咱们一步步拆解解决:

为什么返回int时正常,返回vector<int>时编译失败?

std::adjacent_difference的默认行为是:

  1. 先将第一个输入元素直接复制到输出迭代器
  2. 再对每一对相邻元素(input[i-1], input[i])调用自定义diff函数,将结果写入输出迭代器

当你的输出容器是vector<int>、diff返回int时:第一个输入元素是int,diff结果也是int,类型完全匹配,所以back_inserter能正常工作。

但当输出容器是vector<vector<int>>、diff返回vector<int>时:第一个要输出的元素是int(来自输入的第一个元素),但容器只能接受vector<int>类型,这就触发了编译时类型不匹配错误。

解决方案一:用std::transform处理相邻元素对(推荐)

如果你只需要相邻元素对的diff结果,不需要保留adjacent_difference自带的第一个元素输出,那么std::transform是更合适的选择——它可以直接遍历两对错开的输入迭代器,跳过第一个元素的类型问题:

#include <vector>
#include <algorithm>
#include <iterator>

// 你的自定义diff函数
std::vector<int> dif(int prev, int curr) {
    // 示例:返回差值和和值的组合
    return {curr - prev, curr + prev};
}

int main() {
    std::vector<int> input = {1,2,3,4,5};
    std::vector<std::vector<int>> output;

    if (!input.empty()) {
        // 用两个错开的迭代器遍历相邻元素对
        std::transform(
            input.begin(), std::prev(input.end()),  // 前一个元素的范围
            std::next(input.begin()),               // 当前元素的范围起始
            std::back_inserter(output),             // 输出插入器
            dif                                     // 自定义处理函数
        );
    }

    // 此时output中的元素是:{1,3}, {1,5}, {1,7}, {1,9}
    return 0;
}

解决方案二:保留adjacent_difference语义(含第一个元素)

如果你需要保留adjacent_difference的完整语义(即输出第一个输入元素+后续相邻对的diff结果),可以通过两种方式处理类型不匹配:

方式1:手动处理第一个元素

先手动将第一个输入元素包装成vector<int>插入容器,再对剩余元素调用adjacent_difference:

#include <vector>
#include <numeric>
#include <iterator>

std::vector<int> dif(int prev, int curr) {
    return {curr - prev, curr + prev};
}

int main() {
    std::vector<int> input = {1,2,3,4,5};
    std::vector<std::vector<int>> output;

    if (!input.empty()) {
        // 手动插入第一个元素的包装
        output.push_back({input[0]});
        // 对剩余元素调用adjacent_difference,输出从第二个位置开始
        std::adjacent_difference(
            std::next(input.begin()), input.end(),
            std::next(output.begin()),
            dif
        );
    }

    // 此时output中的元素是:{1}, {1,3}, {1,5}, {1,7}, {1,9}
    return 0;
}

方式2:自定义适配输出迭代器

写一个可以同时接受int和vector<int>的插入迭代器,自动将int包装成vector<int>:

#include <vector>
#include <numeric>
#include <iterator>
#include <utility>

// 自定义插入迭代器,适配int到vector<int>的转换
struct VecBackInserter {
    std::vector<std::vector<int>>& target;

    explicit VecBackInserter(std::vector<std::vector<int>>& vec) : target(vec) {}

    // 处理int类型(第一个元素)
    VecBackInserter& operator=(int val) {
        target.push_back({val});
        return *this;
    }

    // 处理vector<int>类型(diff结果)
    VecBackInserter& operator=(std::vector<int> val) {
        target.push_back(std::move(val));
        return *this;
    }

    // 输出迭代器必需的类型定义和空操作
    using value_type = void;
    using difference_type = void;
    using pointer = void;
    using reference = void;
    using iterator_category = std::output_iterator_tag;

    VecBackInserter& operator*() { return *this; }
    VecBackInserter& operator++() { return *this; }
    VecBackInserter operator++(int) { return *this; }
};

std::vector<int> dif(int prev, int curr) {
    return {curr - prev, curr + prev};
}

int main() {
    std::vector<int> input = {1,2,3,4,5};
    std::vector<std::vector<int>> output;

    std::adjacent_difference(
        input.begin(), input.end(),
        VecBackInserter(output),
        dif
    );

    // 此时output中的元素是:{1}, {1,3}, {1,5}, {1,7}, {1,9}
    return 0;
}

内容的提问来源于stack exchange,提问作者Евгений Куркин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:09:41