一、transform是什么:
在C++标准库中,transform函数是一个非常实用的算法。它可以将一个给定的范围(一个或多个容器)的每个元素应用到一个函数,并将该函数的结果存储在另一容器中,或者覆盖当前范围。代码如下:
template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperator op);
其中,first1和last1构成了一个区间,称为源区间,表示一个向量或数组。result指向存储器中的目标序列,是另一个向量或数组。op是转换操作函数的对象。此函数的任务是将[first1,last1]内的每个元素转换为op(*i),其中i是[first1,last1]所覆盖区间的指向成员的迭代器。
二、transform与lambda表达式:
在应用transform函数时,我们可以使用lambda表达式作为操作函数。Lambda表达式是一种C++的函数表示方式,它可以定义小型匿名函数。即变量可以在lambda函数中定义,在不用命名这些变量的情况下,可以给它们附加一个函数(或操作符)来作为匿名函数体。例如:
std::vector<int> from{1,2,3,4,5};
std::vector<int> to(from.size());
std::transform(from.begin(), from.end(), to.begin(), [](int i){ return i * 2 ; });
这个例子中,lambda表达式[](int i) { return i * 2;}
作为transform的第三个参数被传递。transform函数会取from序列中的每个元素,将它们传递给lambda表达式,并把返回结果赋值给to序列中相应位置的元素。在这个例子中,最终的结果将是to = [2,4,6,8,10]
。这证明了,通过transform函数,我们可以轻松地使用lambda表达式对向量进行操作。
三、transform与自定义函数:
在使用transform函数时,我们还可以使用用户自定义的函数作为操作函数。在使用自定义函数时,需要实现相应的转换操作,以及确定第三个参数(目标序列存储器)的类型。以下是一个将浮点数圆整为整数的示例:
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
int round_to_int(double x)
{
return static_cast<int>(std::round(x));
}
int main()
{
std::vector<double> v{1.0, 2.2, 3.5, 4.7, 9.0};
std::vector<int> result(v.size());
std::transform(v.begin(), v.end(), result.begin(), round_to_int);
// result: [1, 2, 4, 5, 9]
for(auto i : result) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
在本例中,我们向transform函数传递了一个指向转换函数round_to_int
的指针。函数round_to_int
接收一个浮点数,将其四舍五入,返回相应的整数。函数指针作为操作函数的参数。元素被取自v序列,存储在result序列中。根据操作的特点以及需要的结果类型,我们选择了使用int类型的序列作为结果序列存储器。
四、transform与多个容器:
最后,transform函数可以处理多个容器。如果提供了多个源和目标序列,则在指定操作函数时应该使用并置二元函数。此时传递的函数接受两个参数,分别是容器中的对应元素,而不是像unary_function接受的单个值。下面是一个使用二进制函数操作两个向量的简单示例:
#include <iostream>
#include <vector>
#include <algorithm>
int sum(int x, int y)
{
return x + y;
}
int main()
{
std::vector<int> v1 { 1, 2, 3, 4, 5 };
std::vector<int> v2 { 1, 1, 2, 2, 3 };
std::vector<int> result(v2.size());
std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), sum);
for(auto i : result) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
在这个例子中,我们有两个容器v1和v2分别包含整数的元素,在transform函数中传递了一个求和函数,将结果存储在相应位置的另一个容器中。在函数sum中,我们将两个相对应的参数相加并返回结果。最后的结果是result = [2, 3, 5, 6, 8]
。
总结:
本文介绍了C++标准库中的一个非常实用的算法——transform函数。我们详细讨论了transform函数的相关应用,包括使用lambda表达式和自定义函数完成转换任务,以及如何操作多个容器。类似于lambda表达式的功能,transform函数使代码变得更短、更清晰,可读性更高。通过更深入地学习及实践,transform函数可以帮助开发者提高工作效率,使代码量更少但实现同样的功能。