back_insert_iterator-尾插迭代器类

1.传统迭代器能干啥

比如,

cpp 复制代码
vector<int> v = {1,2,3}; 
auto it = v.begin();
*it = 100;

迭代器指向一个确定的元素,通过 *这些来修改这个位置的值

本意是,把原迭代器 src 的值,写到目标迭代器 dest 指向的位置,然后目标迭代器dest移动到下一个位置。

cpp 复制代码
*dest = *src;
++dest;

但有一个场景,

想把一个vector容器中的值,拷贝到另一个空容器当中,也就是往空容器中追加元素,

cpp 复制代码
vector<int> src{1,2,3};
vector<int> dst; // 空的!内部指针为nullptr,管理堆上的空间,还没有malloc
copy(src.begin(), src.end(), dst.begin()); // ❌ _start=nullptr,崩溃!

普通迭代器只能修改已经存在的值,不能自动新增元素

2.引入back_inserter_iterator 迭代器

不绑定固定元素,而是直接绑定一个容器,copy的时候,直接container.push_back()元素

遇到赋值 *dst=val,不写原有位置,直接在尾部追加新元素,

cpp 复制代码
vector<int> src{1,2,3};
vector<int> dst;
copy(src.begin(), src.end(), back_inserter(dst)); // ✅ 完美工作

这样,++是空操作,因为它不存在下一个位置,每次统一追加到末尾

3.看源码具体实现细节

back_inserter是一个函数,拿传入的容器_x,构造一个 back_insert_iterator 对象,返回给我们

cpp 复制代码
template<typename _Container>
inline back_insert_iterator<_Container> back_inserter(_Container& __x)
{ 
    return back_insert_iterator<_Container>(__x);
}

back_insert_iterator是一个模板类,通过它构造出一个迭代器对象,这个对象内部存了容器的指针,操作这个迭代器对象,最终会修改它绑定的容器。

这个对象的目的不是修改某个已经存在的值,而是为了在尾部push_back追加元素,它永远绑定同一个容器,永远在尾部追加。

cpp 复制代码
template<typename _Container>
class back_insert_iterator : public iterator<output_iterator_tag, void, void, void, void>
{
protected:
    _Container* container;

public:
/// A nested typedef for the type of whatever container you used.
// 默认构造
constexpr back_insert_iterator() noexcept : container(nullptr) { }
// 带参构造
back_insert_iterator(_Container& __x) : container(std::__addressof(__x)) { }
// =运算符重载
//左值引用
//const value_type& --const string&
back_insert_iterator& operator=(const typename _Container::value_type& __value) 
{
	container->push_back(__value);
	return *this;
}

//value_type&& --string&&
// 右值引用,container __value,调用容器的移动 push_back,不拷贝,直接转移资源
back_insert_iterator& operator=(typename _Container::value_type&& __value) 
{
	container->push_back(std::move(__value));
	return *this;
}

// * 和 ++ 全是空壳,只是为了适配 STL 算法统一的写法
/// Simply returns *this.  (This %iterator does not @a move.)
back_insert_iterator& operator*()
{ return *this; }

back_insert_iterator& operator++()
{ return *this; }

back_insert_iterator operator++(int)
    { return *this; }
};

4.redis中的使用

cpp 复制代码
vector<string> res;
auto item = std::back_inserter(res);
redis.smembers("key",item);

1.调用back_inserter函数,返回back_insert_iterateo对象

2.调用back_insert_iterator类的拷贝构造,给这个对象内部容器指针绑定vector容器

  1. redis.smembers("key",it),就是把查到的 key 对应的 value,输出到这个 迭代器对象 绑定的容器当中,内部会执行,***item = 拿到的redis元素,operator++(int) ) = val;**会调用operator=()运算符重载,对 item 对象绑定的container容器进行push_back尾插操作。

但如果绑定的容器,比如set,根本没有对应的push_back()方法,就会报错,比如下面的这行


完,感谢阅读。

相关推荐
普通人611 小时前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
猫猫不是喵喵.1 天前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
fish_zzzz4 天前
笔记-论数据结构2
1024程序员节
普通人65 天前
PHP文件读写完全指南
开发语言·php·1024程序员节
Martina_03215 天前
AI生成3D场景从白模换成精模后镜头全偏了?用6步检查单位、枢轴与层级替换
图像处理·人工智能·3d·ai·自然语言处理·材质·1024程序员节
星云_byto6 天前
CSS布局
人工智能·机器学习·目标跟踪·1024程序员节
张小姐的猫9 天前
【MySQL】访问 & 数据流动原理
android·数据库·mysql·adb·1024程序员节
工业HMI实战笔记10 天前
印刷电路板HMI:SMT贴装的元件定位界面
制造·设计规范·设计语言·1024程序员节
Martina_032110 天前
AI生成3D模型一合并网格,材质就串色?用6步检查材质槽、UV与图集重映射
图像处理·人工智能·3d·材质·uv·游戏策划·1024程序员节
橙光成长10 天前
android-ad-cleaner:android免 Root 批量关闭系统开屏与营销推送
android·1024程序员节