【C++】STL 算法 - transform 变换算法 ③ ( transform 和 for_each 算法的区别 | STL 算法接收的可调用对象分析 - 以 transform 为例进行分析)

这篇具有很好参考价值的文章主要介绍了【C++】STL 算法 - transform 变换算法 ③ ( transform 和 for_each 算法的区别 | STL 算法接收的可调用对象分析 - 以 transform 为例进行分析)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、transform 和 for_each 算法的区别



1、transform 和 for_each 算法作用区别


for_each 算法 主要用于 对容器中的每个元素执行某种操作 , 而不一定产生新的值或改变原容器的值 , 可能涉及改变元素的值 , 输出元素的值等 ; 使用该算法常用于 遍历输出到控制台 操作 或 修改原容器中的元素内容 操作 ;

transform 算法 主要用于 对容器中的每个元素进行转换 , 并将结果存储到另一个容器中 , 其执行的是一对一的映射操作 ; 会生成新的序列 , 或者在原地修改序列 ;


2、transform 和 for_each 算法 返回值区别


transform 算法 返回一个迭代器 , 指向输出序列的最后一个元素的下一个位置 , 如果提供了 输出迭代器 , 则 transform 不保证 原容器 的内容不变 ;

for_each 算法 返回一个函数对象 , 一般情况下不会使用该返回值 , for_each 的主要目的是执行遍历操作 , 而不是产生新的序列或返回值 ;


3、transform 和 for_each 算法 接收的 函数对象 参数 和 返回值区别


for_each 算法 接收 的 函数对象 的 参数 一般都是 引用参数 , 返回值为 void ;

transform 算法 接收 的 函数对象 的 参数 一般都是 值参数 , 返回值 必须有类型 , 是输出容器元素类型 ;





二、STL 算法接收的可调用对象分析 - 以 transform 为例进行分析



1、参考代码示例


在下面的代码中 ,

首先 , 创建了一个 vector 数组容器 ,

	// 创建一个 vector 数组容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);

然后 , 使用 transform 算法为每个容器中的元素进行自增操作 , 将自增的元素继续输出到 原来的 数组容器中 ;

	// 向 transform 变换算法中 传入 Lambda 表达式
	transform(myVector.begin(), myVector.end(), myVector.begin(), [](int element) {
		return ++element;
	});

最后 , 使用 for_each 算法遍历 vector 数组容器 , 查看 transform 变换后的结果 ;

	// 遍历容器
	for_each(myVector.begin(), myVector.end(), [](int element) {
		cout << element << endl;
	});

代码示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

int main() {

	// 创建一个 vector 数组容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);

	// 向 transform 变换算法中 传入 Lambda 表达式
	transform(myVector.begin(), myVector.end(), myVector.begin(), [](int element) {
		return ++element;
	});

	// 遍历容器
	for_each(myVector.begin(), myVector.end(), [](int element) {
		cout << element << endl;
	});

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

执行结果 :

10
6
3
8
请按任意键继续. . .

【C++】STL 算法 - transform 变换算法 ③ ( transform 和 for_each 算法的区别 | STL 算法接收的可调用对象分析 - 以 transform 为例进行分析),C++,c++,算法,stl,开发语言,transform,for_each,函数对象


2、transform 函数接收的规则


将 transform 函数的 Lambda 表达式 的 返回值注释掉 ,

	// 向 transform 变换算法中 传入 Lambda 表达式
	transform(myVector.begin(), myVector.end(), myVector.begin(), [](int element) {
		//return ++element;
	});

将 接收 int 参数 , 返回 int 返回值 的 Lambda 表达式 ,

int(int)

变成了 接收 int 参数 , 返回 void 的 Lambda 表达式 ;

void(int)

此时编译时 , 报如下错误 :

1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\algorithm(1310,1): error C2440:=: 无法从“void”转换为“int1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\algorithm(1310,24): message : void 类型的表达式不能转换为其他类型
1>Y:\002_WorkSpace\002_VS\HelloWorld\HelloWorld\Test.cpp(21): message : 查看对正在编译的函数 模板 实例化“_OutIt std::transform<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,main::<lambda_3c270406302a4dd5e2ba2daa1c0faf8f>>(const _InIt,const _InIt,_OutIt,_Fn)”的引用
1>        with
1>        [
1>            _OutIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>,
1>            _Ty=int,
1>            _InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>,
1>            _Fn=main::<lambda_3c270406302a4dd5e2ba2daa1c0faf8f>
1>        ]
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========

【C++】STL 算法 - transform 变换算法 ③ ( transform 和 for_each 算法的区别 | STL 算法接收的可调用对象分析 - 以 transform 为例进行分析),C++,c++,算法,stl,开发语言,transform,for_each,函数对象


3、查看算法函数接收的可调用对象 - 以 transform 函数为例


查看 transform 函数的源码 如下 :

// FUNCTION TEMPLATE transform
template <class _InIt, class _OutIt, class _Fn>
_OutIt transform(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Fn _Func) {
    // transform [_First, _Last) with _Func
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    auto _UDest       = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast));
    for (; _UFirst != _ULast; ++_UFirst, (void) ++_UDest) {
        *_UDest = _Func(*_UFirst);
    }

    _Seek_wrapped(_Dest, _UDest);
    return _Dest;
}

在上述 transform 源码中 , 传入的可调用对象是 _Fn _Func 参数 , 在代码中 , 会调用该 可调用对象 , 并返回一个值 , 使用 *_UDest 接收返回值 ,

    for (; _UFirst != _ULast; ++_UFirst, (void) ++_UDest) {
        *_UDest = _Func(*_UFirst);
    }

之后 , 还要将该返回值 的 地址 作为参数 , 传递给 _Seek_wrapped 函数 ,

_Seek_wrapped(_Dest, _UDest);

这个 _Fn _Func 参数 执行后 , 必须有返回值 ;文章来源地址https://www.toymoban.com/news/detail-793149.html

到了这里,关于【C++】STL 算法 - transform 变换算法 ③ ( transform 和 for_each 算法的区别 | STL 算法接收的可调用对象分析 - 以 transform 为例进行分析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】STL 算法 ⑤ ( 二元函数对象 | std::transform 算法简介 | 为 std::transform 算法传入一元函数对象进行转换操作 )

    \\\" 二元函数对象 \\\" 指的是 一个实例类 中 , 重载了 \\\" 函数调用操作符 () \\\" 函数 operator() , 并且该函数 接受 2 个参数 ; 如果 \\\" 重载 函数调用操作符 () 函数 \\\" 只接收一个参数 , 那么这个函数对象就是 一元函数对象 ; 下面的结构体类 函数对象 , 就是一个二元函数对象 , 其作用是将

    2024年01月18日
    浏览(62)
  • 【C++】STL 算法 ① ( STL 算法相关头文件 | 函数对象 / 仿函数 简介 | 函数调用操作符 | 重写函数调用操作符的类 | 函数对象 与 普通函数区别 )

    标准模板库 STL 算法 都定义在 algorithm , numeric 和 functional 三个头文件中 ; 使用 STL 标准模板库 算法时 , 导入上述 3 个头文件 , 导入时根据需求导入即可 , 不必都导入 ; algorithm 头文件 是 3 个 STL 算法头文件中 包含算法最多的一个 , 包含常用的 : 比较算法、交换算法、查找算法

    2024年01月16日
    浏览(55)
  • 用于多视图 3D 对象检测的位置嵌入变换(PETR: Position Embedding Transformation for Multi-View 3D Object Detection)

    本文PETR (PETR: Position Embedding Transformation for Multi-View 3D Object Detection)是对DETR3D (3D Object Detection from Multi-view Images via 3D-to-2D Queries)的改进,将2D转换至3D,还存在三个问题: (1) 空间与多视图之间的信息交互依赖于3D参考点估计的准确性,使得采样的特征超出了对象区域,无法投影

    2024年02月07日
    浏览(50)
  • list_for_each_entry详解

    参考链接: 终于理解list_entry和list_for_each_entry linux 内核代码中list_for_each_entry宏之我见 linux之list_for_each和list_for_each_entry函数 container_of的用法 用户态下的list.h Linux内核中的许多链表操作,都是使用list_for_each_entry进行遍历,其定义在/usr/src/linux-2.6.32.9/include/linux/list.h路径,具体

    2024年02月15日
    浏览(39)
  • 【C++】STL 算法概念和分类 ( STL 算法头文件 | STL 算法思想 - 数据与算法分离 | STL 算法 迭代器 | STL 算法 操作对象 | STL 算法分类 )

    标准模板库 STL 算法 都定义在 algorithm , numeric 和 functional 三个头文件中 ; 使用 STL 标准模板库 算法时 , 导入上述 3 个头文件 , 导入时根据需求导入即可 , 不必都导入 ; algorithm 头文件 是 3 个 STL 算法头文件中 包含算法最多的一个 , 包含常用的 : 比较算法、交换算法、查找算法

    2024年01月21日
    浏览(54)
  • 【时间序列】Transformer for TimeSeries时序预测算法详解

    2017年,Google的一篇  Attention Is All You Need  为我们带来了Transformer,其在NLP领域的重大成功展示了它对时序数据的强大建模能力,自然有人想要把Transformer应用到时序数据预测上。在Transformer的基础上构建时序预测能力可以突破以往的诸多限制,最明显的一个增益点是,Transfo

    2024年02月16日
    浏览(49)
  • 深入理解 Java 循环结构:while、do while、for 和 for-each 循环

    循环可以执行一个代码块,只要达到指定的条件。循环很方便,因为它们节省时间,减少错误,并使代码更易读。 while 循环会循环执行一个代码块,只要指定的条件为真: 语法 在下面的示例中,只要变量(i)小于 5,循环中的代码将一遍又一遍地运行: 示例 注意:不要忘

    2024年02月19日
    浏览(39)
  • Terraform 系列-使用 for-each 对本地 json 进行迭代

    Terraform 系列文章 Grafana 系列文章 前文 Grafana 系列 - Grafana Terraform Provider 基础 介绍了使用 Grafana Terraform Provider 创建 Datasource. 现在有这么一个现实需求: 有大量的同类型 (type) 的 datasource 需要批量添加,而且这些 datasource 的基本信息是以 json 的格式已经存在。 需要对 json 进行

    2024年02月10日
    浏览(45)
  • 【嵌入式——C++】算法(STL)

    需要引入头文件 #include algorithm 遍历容器。 代码示例 搬运容器到另一个容器中。参数1 原容器起始迭代器,参数2 原容器结束迭代器,参数3 目标容器开始迭代器 参数4 函数或者仿函数。 代码示例 查找元素,查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器

    2024年02月19日
    浏览(42)
  • C++系列二:STL教程-常用算法

    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 还有一些我在尝试中迷惑不解的,有点玄幻。 排序算法: 合并算法: 查找算法: 筛选分组算法: 其他:

    2024年02月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包