首先看一下transform函数的用户手册:
template < class InputIterator, class OutputIterator, class UnaryOperator >
OutputIterator transform ( InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op );
template < class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperator >
OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperator binary_op );
使用案例:
#include
#include
#include
using namespace std;
int main()
{
string str = "Hello World!";
transform(str.begin(), str.end(), str.begin(),tolower);
cout << str << endl;
}
在VS下这个程序编译运行都很正常,但是在G++下编译就不是那么回事了。今天写这篇博客的目的就是解决这里出现的错误。
G++编译错误信息如下
tham@root-laptop:~/Desktop$ g++ -o test test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: no matching function for call to
‘transform(__gnu_cxx::__normal_iterator,
std::allocator > >, __gnu_cxx::__normal_iterator, std::allocator > >,
__gnu_cxx::__normal_iterator,
std::allocator > >, )’
最后两句话可以看出,是重载函数出现了错误。请教Google,发现tolower/toupper函数有两个定义:
以及
template
charT std::toupper(charT, const locale&);// from
编译器并不能分辨两个函数的区别,导致编译错误。此时我们便要告诉编译器,使用哪一个函数,看例子:
#include
#include
#include
using namespace std;
int main()
{
string str = "Hello World!";
transform(str.begin(), str.end(), str.begin(), (int(*)(int)) tolower);
cout << str << endl;
}
其中,(int(*)(int))为函数指针类型,告诉编译器要调用“输入参数是一个int,返回值也是int”的函数。如果不了解函数指针的用法,可以请教Google,这里不再赘述。
transform函数的作用是:将某操作应用于指定范围的每个元素。transform函数有两个重载版本:
transform(first,last,result,op);//first是容器的首迭代器,last为容器的末迭代器,result为存放结果的容器,op为要进行操作的一元函数对象或sturct、class。
transform(first1,last1,first2,result,binary_op);//first1是第一个容器的首迭代器,last1为第一个容器的末迭代器,first2为第二个容器的首迭代器,result为存放结果的容器,binary_op为要进行操作的二元函数对象或sturct、class。
注意:第二个重载版本必须要保证两个容器的元素个数相等才行,否则会抛出异常。
看一个例子:利用transform函数将一个给定的字符串中的小写字母改写成大写字母,并将结果保存在一个叫second的数组里,原字符串内容不变。
我们只需要使用transform的第一个重载函数,当然我们也可以使用for_each函数来完成再copy几次就行了,现在来看一下代码:
#include
#include
using namespace std;
char op(char ch)
{
if(ch>='A'&&ch<='Z')
return ch+32;
else
return ch;
}
int main()
{
string first,second;
cin>>first;
second.resize(first.size());
transform(first.begin(),first.end(),second.begin(),op);
cout<
再看一个例子:给你两个vector向量(元素个数相等),请你利用transform函数将两个vector的每个元素相乘,并输出相乘的结果。
#include
#include
#include
using namespace std;
void print(int &elem){cout< A,B,SUM;
int n;
cin>>n;
for(int i=0;i>t;
A.push_back(t);
}
for(int i=0;i>t;
B.push_back(t);
}
SUM.resize(n);
transform(A.begin(),A.end(),B.begin(),SUM.begin(),op);
for_each(SUM.begin(),SUM.end(),print);
return 0;
}
输入:
网上复制的例子
#include
#include
#include
#include
using namespace std;
class Print
{
public:
void operator () (int val)
{
cout << val << " " ;
}
};
int main()
{
int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9} ;
vector vec1(arr1, arr1 + sizeof arr1 / sizeof (int)) ;
vector vec2(9, 0) ;
// transform(beg, end, dest, unaryOp) ;
// 操作前:[beg,end)标示输入序列.dest是目标迭代器.unaryOp是一元函数对象.
// 操作后:对[beg,end)中每个元素应用unaryOp操作并将结果复制到dest迭代器所在的容器中.
// 返回值:返回目标容器中被写入的最后一个位置的下一个迭代器.
// 备注: [dest,...)必须能够存储[beg,end)中的全部元素.否则将抛出异常.
transform(vec1.begin(), vec1.end(), vec2.begin(), bind2nd(plus (), 1000)) ;
for_each(vec2.begin(), vec2.end(), Print()) ;
// transform(beg, end, beg2, dest, binaryOp) ;
// 操作前:[beg,end)标示输入序列.[beg2,...)标示输入序列.dest是目标迭代器..binaryOp是二元函数对象.
// 操作后:[beg,end)序列中的元素依次作为二元操作的第一个实参.
// [beg2,...)序列中的元素依次作为二元操作的第二个实参.将运算结果依次复制到dest迭代器所在的容器中.
// 返回值:返回目标容器中被写入的最后一个元素的下一个位置的迭代器.
// 备注: [beg2,...)必须能够存储[beg,end)中的全部元素.
// [dest,...)必须能够存储[beg,end)中的全部元素.否则将抛出异常
vector vec3(18, 1) ;
transform(vec1.begin(), vec1.end(), vec2.begin(), vec3.begin(), multiplies ()) ;
for_each(vec3.begin(), vec3.end(), Print()) ;
return 0 ;
}