2、表示操作数类型的模板类型
每个函数对象类都是一个类模板,我们需要为该模板提供一个类型:
plusstrAdd; plus intAdd;
应用:
plusstrAdd; cout << strAdd("Hello ","World\n"); plus intAdd; negate intNegate; cout << intAdd(10,20) << endl; int sum = intAdd(10,intNegate(20)); cout << sum << endl;
3、在算法中使用标准库函数对象
函数对象常用于覆盖算法使用的默认操作符。例如,sort默认使用operator<按升序对容器进行排序。为了按降序对容器进行排序,可以传递函数对象greater。该类将产生一个调用操作符,调用基础对象的大于操作符。
sort(strVec.begin(),strVec.end(),greater()); //降序排序
//附:完整程序测试 void printVec(const vector&vec) { for (vector ::const_iterator iter = vec.begin(); iter != vec.end(); ++iter) { cout << *iter << '\t'; } cout << endl; } int main() { ifstream inFile("input"); vector strVec; string word; while (inFile >> word) { strVec.push_back(word); } sort(strVec.begin(),strVec.end()); //升序排序 printVec(strVec); sort(strVec.begin(),strVec.end(),greater ()); //降序排序 printVec(strVec); }
第二个sort函数的第三个实参greater
三、函数对象的函数适配器
标准库提供了一组函数适配器,用于特化和扩展一元和二元函数对象。函数适配器分为:
1、绑定器:是一种函数适配器,它通过将一个操作数绑定到给定值,而将二元函数对象转换为一元函数对象。有:bind1str,bind2nd.
每个绑定器接受一个函数对象和一个值,bind1st将给定值绑定到二元函数对象的第一个实参,bind2nd将给定值绑定到二元函数对象的第二个实参。
//计算容器中所有小于或等于 10 的元素的个数
count_if(vec.begin(),vec.end(),bind2nd(less_equal
(),10));
该适配器返回一个函数对象,该对象用10作右操作数应用<=操作符,调用计算输入范围中小于或等于10的元素的个数。
2、求反器:将谓词函数的真值求反。有:not1和not2。
not1将一元函数对象的真值求反,not2将二元函数对象的真值求反。
//是对不 <= 10[即:> 10] 的那些元素进行计数
count_if(vec.begin(),vec.end(),
not1(bind2nd(less_equal
(),10)));
//P453 习题14.37
//(a)
int main()
{
vector
ivec;
ifstream inFile("input");
int val;
while (inFile >> val)
{
ivec.push_back(val);
}
typedef vector
::iterator iterType; iterType iter = ivec.begin(); while ((iter = find_if(iter,ivec.end(),bind2nd(greater
(),10))) != ivec.end()) { cout << *iter << endl; ++ iter; } }
//(b)
int main()
{
vector
strVec;
ifstream inFile("input");
string val;
while (inFile >> val)
{
strVec.push_back(val);
}
typedef vector
::iterator iterType; iterType iter = strVec.begin(); //主要的改动在于是换成了not_equal_to while ((iter = find_if(iter,strVec.end(), bind2nd(not_equal_to
(),"pooh"))) != strVec.end()) { cout << *iter << endl; ++ iter; } }
//(3)
int main()
{
vector
ivec;
ifstream inFile("input");
int val;
while (inFile >> val)
{
ivec.push_back(val);
}
typedef vector
::iterator iterType; multiplies
intMulti; for (iterType iter = ivec.begin(); iter != ivec.end(); ++iter) { *iter = intMulti(*iter,2); } /**或者使用标准库算法:transform *transform(ivec.begin(),ivec.end(),ivec.begin(),bind2nd(multiplies
(),2)); */ for (iterType iter = ivec.begin(); iter != ivec.end(); ++iter) { cout << *iter << endl; } }
//习题14.39
int main()
{
ifstream inFile("input");
vector
words;
string word;
while (inFile >> word)
{
words.push_back(word);
}
cout << "And " << count_if(words.begin(),words.end(),GT_cls(3))
<< " words`s size is equal to 3 or longer" << endl;
greater_equal
sizeGreEQ; string::size_type wc = 0; for (vector
::iterator iter = words.begin(); iter != words.end(); ++iter) { if (sizeGreEQ(iter -> size(),3)) ++ wc; } cout << "And " << wc << " words`s size is equal to 3 or longer" << endl; }