变换主要函数有:
- transform() :将某操作应用于指定范围的每个元素。
transform函数模板的行为等效于:
template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op)
{
while (first1 != last1) {
*result = op(*first1); // or: *result=binary_op(*first1,*first2++);
++result; ++first1;
}
return result;
}
可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。
例子:
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
int func1(int value){
return value * 2;
}
int main() {
int a[5] = {1, 2, 3, 4, 5};
vector<int> v1(a, a+ 5);
vector<int> v2(5); //初始有5个int大小
cout<< "原始向量v1 = ";
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout<< endl;
cout<< "v1 * 2 --> v1 = ";
transform(v1.begin(), v1.end(), v1.begin(), func1);//调用一元函数
copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
cout<< endl;
return 0;
}
在这里第三个参数指向输入容器的元素的迭代器。调用func1函数将value乘2,第三个参数是输入序列的开始迭代器,应用第 4 个参数指定的函数的结果会被存回它所运用的元素上。
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
int func2(int value1, int value2){
return value1 + value2;
}
int main() {
int a2[5] = {1, 2, 3, 4, 5};
int b2[5] = {6, 7, 8, 9, 10};
int c2[5];
cout<< "a2[5] = ";
copy(a2, a2 + 5, ostream_iterator<int>(cout, " "));
cout<< endl;
cout<< "b2[5] = ";
copy(b2, b2 + 5, ostream_iterator<int>(cout, " "));
cout<< endl;
cout<< "a2 + b2 --> c2 = ";
transform(a2, a2 + 5, b2, c2, func2); //调用二元函数
copy(c2, c2 + 5, ostream_iterator<int>(cout, " "));
return 0;
}
二元函数模板:
- 前两个参数是第一个输入序列的输入迭代器。
- 第3个参数是第二个输入序列的开始迭代器,显然,这个序列必须至少包含和第一个输入序列同样多的元素。
- 第4个参数是一个序列的输出迭代器,它所指向的是用来保存应用函数后得到的结果的序列的开始迭代器。
- 第5个参数是一个函数对象,它定义了一个接受两个参数的函数,这个函数接受来自两个输入序列中的元素作为参数,返回一个可以保存在输出序列中的值。
transform函数分为一元和二元两个模板,上文演示了transform 如何调用一元函数及二元函数。结果可以修改自己,如transform(v1l.begin(),vl. end(),v1. begin(),funcl);也可以形成新的集合,如transform(v1.begin(),v1.end(),v2.begin(),func1)。为了避免初始容器大小的冲突,可以通过加back_inserter解决,如transform (v1.begin(), v1.end(), back_inserter(v), func1);
既然调用的是一元或二元函数,我们可以结合STL中提供的系统函数对象。如transform(v1. begin(),v1.end(),v2.begin(),func1)可以修改为transform(v1.begin(),v1.end(),v2.begin(),bind2nd(multiplies≤int>(),2 ));如transform(a2,a2+5,b2,c2,func2)可以修改为transform(a2,a2+5,b2,c2,plus())。当然,不要忘记加包含文件#include 。
根据transform的功能,我们可以写一个字符串加密程序:
#include <iostream>
#include <fstream>
#include <string>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
template<class T>
class Encrypt {
};
template<> //模板特化
class Encrypt<string> {
public:
string operator()(const string& src) {
string s;
for_each(src.begin(), src.end(), [&s](char c) {
c = c + 1;
s.push_back(c);
});
return s;
}
};
int main() {
string strText;
vector<string> v;
vector<string> vResult;
ifstream in("d:\\b.txt"); //内容为: Hello World!
while (!in.eof()) {
getline(in, strText, '\n');
v.push_back(strText);
}
in.close();
transform(v.begin(), v.end(), back_inserter(vResult), Encrypt<string>());
copy(vResult.begin(), vResult.end(), ostream_iterator<string>(cout, " "));
return 0;
}
在函数对象类Encrypt中,将字符串中对应字符ASCII 加1即是加密结果。当然我们也可以将Encrypt类转换为lambda函数:
transform(v.begin(), v.end(), back_inserter(vResult), [](const string& src) {
string s;
for_each(src.begin(), src.end(), [&s](char c) {
c = c + 1;
s.push_back(c);
});
return s;
});