c++ bug 记录(merge函数调用时错误地传入了vector对象而非迭代器。)
bug代码:
/*函数方法定义实现
*/void test11() {vector<int> v1 = { 1,2,5,6 };vector<int> v2 = { 3,4,7,9 };vector<int> vt;//目标向量vt.resize(v1.size() + v2.size());merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vt);for_each(vt.begin(), vt.end(), print01);}
void print01(int val) {cout << val << " ";
}
bug原因分析:
一、先看报错信息
plaintext
错误 C2100 无法取消引用类型为“_OutIt”的操作数
错误 C2675 一元“++”:“_OutIt”不定义该运算符或到预定义运算符可接收类型的转换
with
[_OutIt=std::vector<int,std::allocator<int>>
]
_OutIt
是merge
模板的输出迭代器类型。- 这里编译器把
_OutIt
推断成了std::vector<int>
(整个容器),而不是迭代器。 merge
内部会对输出迭代器做两件事:*result = value;
(解引用赋值)++result;
(移动到下一个位置)
- 但
vector
本身是容器,不是迭代器,不能*vector
也不能++vector
,所以报错。
二、问题出在哪一行?
cpp
运行
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vt);
merge
的前四个参数是输入范围的迭代器,第五个参数要求是 输出迭代器(指向存放结果的位置)。你传的 vt
是 vector<int>
对象,而不是迭代器,所以类型错了。
三、正确写法
应该传 输出迭代器,而不是容器本身。因为你已经 resize
了 vt
,有足够空间,可以直接用 vt.begin()
作为输出位置:
cpp
运行
merge(v1.begin(), v1.end(),v2.begin(), v2.end(),vt.begin()); // ✅ 传迭代器
四、完整可运行代码
cpp
运行
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;void print01(int val) {cout << val << " ";
}void test11() {vector<int> v1 = { 1,2,5,6 };vector<int> v2 = { 3,4,7,9 };vector<int> vt;vt.resize(v1.size() + v2.size()); // 提前分配空间// 正确写法:传输出迭代器 vt.begin()merge(v1.begin(), v1.end(),v2.begin(), v2.end(),vt.begin());for_each(vt.begin(), vt.end(), print01);
}int main() {test11();return 0;
}
输出:
plaintext
1 2 3 4 5 6 7 9
五、补充:如果你不想手动 resize
可以用 back_inserter
(定义在 <iterator>
)让 merge
自动 push_back
:
cpp
运行
#include <iterator> // back_inserter 头文件vector<int> vt; // 不用提前 resize
merge(v1.begin(), v1.end(),v2.begin(), v2.end(),back_inserter(vt)); // 自动插入到 vt 末尾
这样就不需要手动分配空间,更安全。
六、总结 bug 原因
- 直接传了
vector
对象给merge
的输出参数,而merge
需要的是迭代器; - 容器不是迭代器,不能解引用和递增,导致编译报错;
- 修复方法:
- 如果容器已分配好空间,用
vt.begin()
; - 如果容器未分配空间,用
back_inserter(vt)
自动插入。
- 如果容器已分配好空间,用