首页 > 其他分享 >std::remove并非你所想

std::remove并非你所想

时间:2022-09-28 20:14:50浏览次数:42  
标签:std ids remove First UFirst 并非 UNext

目录

结论

  1. std::remove并没有删除元素,只是将指定元素交换到了容器后面
  2. 删除元素需要配合erase完成

实现过程

  1. 代码
	// 演示代码
	std::vector<int> ids{ 1, 3, 5, 3, 7 };                   // 1 3 5 3 7
	auto tar = std::remove(ids.begin(), ids.end(), 3);       // 1 5 7 3 7

	// 实现代码
	template <class _FwdIt, class _Pr>
	_NODISCARD _CONSTEXPR20 _FwdIt remove_if(_FwdIt _First, const _FwdIt _Last, _Pr _Pred) {
	// remove each satisfying _Pred
	_Adl_verify_range(_First, _Last);
	auto _UFirst      = _Get_unwrapped(_First);
   	const auto _ULast = _Get_unwrapped(_Last);
   	_UFirst           = _STD find_if(_UFirst, _ULast, _Pass_fn(_Pred));
   	auto _UNext       = _UFirst;
   	if (_UFirst != _ULast) {
        while (++_UFirst != _ULast) {
            if (!_Pred(*_UFirst)) {
                *_UNext = _STD move(*_UFirst);
                ++_UNext;
           	}
       	}
   	}

   	_Seek_wrapped(_First, _UNext);
   	return _First;
	}
  1. 解析
    step1: 1 3 5 3 7 // 原始数据
    step2: _UFirst = 1 _UNext = 1
    step3: 1 5 5 3 7 // 5 != 3 将5向前拷贝到3
    step4: 1 5 5 3 7 // 3 == 3 保持不动
    step5: 1 5 7 3 7 // 7 != 3 将7向前拷贝到5
    step6: swap _First _UNext得到可以删除的迭代器,该迭代器后面所有元素可以删除

注意事项

  1. remove后指定元素并没有被删除
  2. remove后最后元素内容发生变化
  3. 删除元素需要配合erase完成
    std::vector<int> ids{ 1,3,5, 3, 7 };
    auto tar = std::remove(ids.begin(), ids.end(), 3);
    ids.erase(tar, ids.end());

标签:std,ids,remove,First,UFirst,并非,UNext
From: https://www.cnblogs.com/faithlocus/p/16739382.html

相关文章

  • C++11:std::move和std::forward
    标准库函数std::move既然编译器只对右值引用才能调用转移构造函数和转移赋值函数,而所有命名对象都只能是左值引用,如果已知一个命名对象不再被使用而想对它调用转移构造函数......
  • 全志D1H芯片 Tina 如何查看通过 procd init 脚本启动的应用输出到 stdout/stderr 的打
    问题描述当我们使用procdinit脚本让某个应用程序实现开机自启时,会发现应用程序中原本通过printf/fprintf等输出到stdout/stderr的打印信息都无法从串口或adbshell......
  • lc19 removeNthFromEnd(node) 链表删除
    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]classSolu......
  • C/C++ __cdecl和__stdcall的区别和联系
    函数的调用约定涉及了函数参数的入栈顺序、清栈主体(负责清理栈的主体:函数自身还是调用函数者?)、部分名称重整。如,在C编译方式下有_stdcall、_cdecl等调用约定,在C++编译方式......
  • C/C++ x86-64的调用约定,忽略__stdcall、__cdecl、__fastcall、_thiscal
    在设计调用约定时,x64体系结构利用机会清除了现有Win32调用约定(如__stdcall、__cdecl、__fastcall、_thiscall等)的混乱。在Win64中,只有一个本机调用约定而__cdecl......
  • 解决NotePad++中文乱码(由于系统问题),并非NotePad++设置导致的乱码解决!
    1.打开注册表编辑器:【运行命令行:regedit】2.找到注册表HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/FontAssoc3.正常情况下,会有AssociatedDeaultFonts、Ass......
  • RemoveDuplicateAnalyzers
    <TargetName="RemoveDuplicateAnalyzers"BeforeTargets="CoreCompile"> <RemoveDuplicatesInputs="@(Analyzer)"> <OutputTaskParameter="Filtered"ItemName="F......
  • std::bind()功能学习
    转自:https://blog.csdn.net/Jxianxu/article/details/1073820491.介绍std::bind的头文件是<functional>,它是一个函数适配器,接受一个可调用对象(callableobject),生成一个......
  • C++ std : : stack
    和其他序列容器相比,stack是一类存储机制简单、所提供操作较少的容器。下面是stack容器可以提供的一套完整操作:top():返回一个栈顶元素的引用,类型为T&。如果栈为空,返回......
  • centos7 解决libstdc++.so.6.0.19版本问题
    问题描述:ImportError:/usr/lib64/libstdc++.so.6:version`CXXABI_1.3.8’notfound查看:[root@localhostlib64]#find/-namelibstdc++.so.6/usr/lib64/libstdc......